Extend objects

by Maksim Kachurin

JavaScript

// createAssigner from underscore
const createAssigner = function({ defaults, deep, clone, extendArrays = false } = {}) {
    return function replacer(obj) {      	
        if (Array.isArray(obj) && !extendArrays) {
        	return obj;
        }
        
        if (defaults) {
     	   obj = Object(obj);
        }
        
        if (clone) {
        	obj = {};
        }
      	
        const length = arguments.length;
        
        if (length < 2 || obj == null) {
        	return obj;
        }
        
        for (let index = Number(!clone); index < length; index++) {
            const source = arguments[index];
            
            if (typeof source === 'object') {
                const keys = Object.keys(source);
                const l = keys.length;

                for (var i = 0; i < l; i++) {
                    const key = keys[i];

                    // TODO extend array items
                    // deep
                    if (deep && typeof obj[key] === 'object' && typeof source[key] === 'object') {
                        // objects
                        replacer(obj[key], source[key]);
                    }
                    // plain
                    else if (!defaults || obj[key] === void 0) {
                        obj[key] = source[key];
                    }
                }
            }
        }
        
        return obj;
    };
};


window._ = {};
_.defaults = createAssigner({ defaults: true });
_.deepDefaults = createAssigner({ deep: true, defaults: true });

_.extend   = createAssigner();
_.deepExtend = createAssigner({ deep: true });
  
  
window.example1 = {
    a: 1,
    b: 2,
    c: 3,
    z: {
        x: 4,
        y: 5,
        w: 6
    }
};

window.example2 = {
    a: 'replaced2',
    d: 'new2',
    z: {
        x: 'replaced2',
        u: 'new2'
    },
    i: [{ a: 1 }, { a: 2, b: 0 }]
};

window.example3 = {
    b: 'replaced3',
    d: 'replaced3',
    e: 'new3',
    z: {
        y: 'replaced3',
        t:...