我正在寻找一种将两个配置对象合并在一起的方法,例如:
var developmentConfig = {
url: "localhost",
port: 80
};
var productionConfig = {
url: "example.com"
};
var config = isDevelopment ? developmentConfig : jQuery.extend(developmentConfig, productionConfig);
然而,这是一个Node.js应用程序,我不想包含jQuery,我正在寻找类似但独立的东西。我知道我自己可以编写类似的东西,但我宁愿使用经过测试和验证的东西(有边缘情况,配置对象使用更丰富的层次结构时会出现复杂情况等。)
编辑:简单的迭代是不够的,因为它不处理层次结构。也没有下划线的extend
。
答案 0 :(得分:19)
如果您只需要扩展,那么在几行中编写它非常简单。如果你想要递归扩展,如果你想要有圆形结构,带有复杂原型链的对象等,那么完全做到这一点是很棘手的。如果它只是一些嵌套的普通对象,那么这应该有效:
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;
}
如果您正在寻找一个轻量级库来执行此操作(减去递归,由于上面列出的原因)以及javascript未提供的其他类似函数,请查看Underscore,它也可通过NPM获取节点
答案 1 :(得分:5)
这个问题的未来朝圣者的简单独立功能的另一个例子,保护不同类型的属性合并:
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;
}
用法:
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 } }
答案 2 :(得分:3)
此解决方案可创建新对象,并能够处理多个对象。
此外,递归您可以选择想要的天气来覆盖值和对象。< / p>
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 );
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}