I\'m looking for a way to merge two configuration objects together, something like:
var developmentConfig = {
url: \"localhost\",
port: 80
};
var produc
This solution creates a new object and is able to handle multiple objects.
Furthermore, it is recursive and you can chose weather you want to overwrite Values and Objects.
function extendObjects() {
var newObject = {};
var overwriteValues = false;
var overwriteObjects = false;
for ( var indexArgument = 0; indexArgument < arguments.length; indexArgument++ ) {
if ( typeof arguments[indexArgument] !== 'object' ) {
if ( arguments[indexArgument] == 'overwriteValues_True' ) {
overwriteValues = true;
} else if ( arguments[indexArgument] == 'overwriteValues_False' ) {
overwriteValues = false;
} else if ( arguments[indexArgument] == 'overwriteObjects_True' ) {
overwriteObjects = true;
} else if ( arguments[indexArgument] == 'overwriteObjects_False' ) {
overwriteObjects = false;
}
} else {
extendObject( arguments[indexArgument], newObject, overwriteValues, overwriteObjects );
}
}
function extendObject( object, extendedObject, overwriteValues, overwriteObjects ) {
for ( var indexObject in object ) {
if ( typeof object[indexObject] === 'object' ) {
if ( typeof extendedObject[indexObject] === "undefined" || overwriteObjects ) {
extendedObject[indexObject] = object[indexObject];
}
extendObject( object[indexObject], extendedObject[indexObject], overwriteValues, overwriteObjects );
} else {
if ( typeof extendedObject[indexObject] === "undefined" || overwriteValues ) {
extendedObject[indexObject] = object[indexObject];
}
}
}
return extendedObject;
}
return newObject;
}
var object1 = { a : 1, b : 2, testArr : [888, { innArr : 1 }, 777 ], data : { e : 12, c : { lol : 1 }, rofl : { O : 3 } } };
var object2 = { a : 6, b : 9, data : { a : 17, b : 18, e : 13, rofl : { O : 99, copter : { mao : 1 } } }, hexa : { tetra : 66 } };
var object3 = { f : 13, g : 666, a : 333, data : { c : { xD : 45 } }, testArr : [888, { innArr : 3 }, 555 ] };
var newExtendedObject = extendObjects( 'overwriteValues_False', 'overwriteObjects_False', object1, object2, object3 );
Contents of newExtendedObject:
{"a":1,"b":2,"testArr":[888,{"innArr":1},777],"data":{"e":12,"c":{"lol":1,"xD":45},"rofl":{"O":3,"copter":{"mao":1}},"a":17,"b":18},"hexa":{"tetra":66},"f":13,"g":666}
Fiddle: http://jsfiddle.net/o0gb2umb/
If all you need is extend, then it's pretty simple to write that in a couple of lines. If you want recursive extension, it's tricky to do that completely generically if you want have circular structures, objects with complex prototype chains, etc. If it's just some nested plain objects, then this should work:
function extend (target, source) {
target = target || {};
for (var prop in source) {
if (typeof source[prop] === 'object') {
target[prop] = extend(target[prop], source[prop]);
} else {
target[prop] = source[prop];
}
}
return target;
}
If you're looking for a lightweight library that does this (minus the recursion, for the reasons listed above) and other similar functions not provided by javascript, look at Underscore which is available via NPM for node too.
One more example of simple standalone function for future pilgrims across this question with protection from merge of the properties of different types:
function extend(obj) {
Array.prototype.slice.call(arguments, 1).forEach(function(source) {
if (source) {
for (var prop in source) {
if (source[prop].constructor === Object) {
if (!obj[prop] || obj[prop].constructor === Object) {
obj[prop] = obj[prop] || {};
extend(obj[prop], source[prop]);
} else {
obj[prop] = source[prop];
}
} else {
obj[prop] = source[prop];
}
}
}
});
return obj;
}
Usage:
extend({ name:'Maria', address:{ city:'Moscow', street:'Lenina str, 52' } }, { name:'Marianna', address:{ zip:1200003 }})
=> { name:'Marianna', address:{ city:'Moscow', street:'Lenina str, 52', zip:1200003 } }