Skip to content

Instantly share code, notes, and snippets.

@brianmriley
Last active December 23, 2015 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianmriley/6701358 to your computer and use it in GitHub Desktop.
Save brianmriley/6701358 to your computer and use it in GitHub Desktop.
Native JavaScript function that performs deep-copy/merge capabilities on n number of arguments. Returns merged object. Adapted from: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
var obj1 = {
"foo": {
"dog": "000"
},
"bar": {
"bear": "111"
},
"tee": {
"elephant": "555"
}
};
var obj2 = {
"foo": {
"cat": "222"
},
"bar": {
"monkey": "333"
},
"moo": {
"snake": "444"
}
};
/**
* Function takes any number of arguments. It can be used to merge objects and makes deep copies of
* values. However, first argument is given by reference.
*
* @returns {*}
*/
function merge() {
/**
* Determines if an object is valid.
*
* @param {Object} obj The object being checked for validity.
* @returns {boolean} Boolean value indicating if the object is valid.
* @private
*/
var _isValidObject = function(obj) {
return ( (typeof obj !== 'object') || (obj === null) );
}
/**
* Inner function that merges two object and their properties.
*
* @param {Object} dst The destination object that contains the merged properties.
* @param {Object} src The source object that's being merged into the destination object.
* @returns {*} The final, merged object; aka the destination object.
* @private
*/
var _mergeObjects = function(dst, src) {
if(_isValidObject(src)) {
return dst;
}
for(var p in src) {
if(!src.hasOwnProperty(p)) {
continue;
}
if(src[p] === undefined) {
continue;
}
if(_isValidObject(src[p])) {
dst[p] = src[p];
} else if(_isValidObject(dst[p])) {
dst[p] = _mergeObjects(src[p].constructor === Array ? [] : {}, src[p]);
} else {
_mergeObjects(dst[p], src[p]);
}
}
return dst;
};
// Loop through arguments and merge them into the first argument.
var out = arguments[0];
if(_isValidObject(out)) {
return out;
}
for(var i = 1, il = arguments.length; i < il; i++) {
_mergeObjects(out, arguments[i]);
}
return out;
}
var mergedObject = merge(obj1, obj2);
/*
// Result
mergedObject = {
bar: {
bear: "111",
monkey: "333"
},
foo: {
cat: "222",
dog: "000"
},
moo: {
snake: "444"
},
tee: {
elephant: "555"
}
}
*/
@ThomasBurleson
Copy link

Some clarity on the for loop:

for(var p in src) 
{   
    if( src.hasOwnProperty(p) ) 
    {
        var sVal    = src[ p ],
            dVal    = dst[ p ];

        if( sVal !== undefined) 
        {
            if( _isValidObject( sVal )) 
            {
                dst[p] = sVal;
            }
            else if( _isValidObject( dVal )) 
            {
                dst[p] = _mergeObjects ( 
                            sVal.constructor === Array ? [] : {}, 
                            sVal 
                        );

            } else {
                _mergeObjects( dVal, sVal );
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment