我需要能够在运行时合并两个(非常简单)JavaScript对象。例如,我想:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。
我需要能够在运行时合并两个(非常简单)JavaScript对象。例如,我想:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。
当前回答
如果您需要一个深度合并,它也将通过将数组串联到结果中来“合并”数组,那么这个ES6函数可能就是您需要的:
函数deepMerge(a,b){//如果两者都不是对象,请返回其中一个:如果(对象(a)!==a&&对象(b)!==b) 返回b||a;//用空对象/数组替换剩余的基元如果(对象(a)!==a) a=Array.isArray(b)?[] : {};if(对象(b)!==b) b=Array.isArray(a)?[] : {};//区别对待阵列:if(Array.isArray(a)&&Array.isArray(b)){//合并阵列被解释为其深层克隆的串联:return[…a.map(v=>deepMerge(v)),…b.map(v=>deepMerger(v)];}其他{//获取任一对象中存在的键var keys=新集合([…Object.keys(a),…Object.key(b)]);//重复并分配给新对象return Object.assign({},…Array.from(keys,key=>({[key]:deepMerge(a[key],b[key])}));}}//演示的示例数据:变量a={组:[{组:[{name:“John”,年龄:12岁},{name:“Mary”,年龄:20岁}],groupName:'对'}],配置:{颜色:“蓝色”,范围:'远'}};变量b={组:[{组:[{name:'比尔',年龄:15岁}],groupName:'孤独者'}],配置:{范围:'关闭',强度:'平均'}};var merged=deepMerge(a,b);console.log(合并);.作为控制台包装{最大高度:100%!重要;顶部:0;}
请注意,如果只有一个参数传递给此函数,它将充当深度克隆函数。
其他回答
最好的方法是使用Object.defineProperty添加一个不可枚举的适当属性。
通过这种方式,您仍然可以迭代对象财产,而无需使用Object.prototype.extend创建属性时新创建的“extend”。
希望这有助于:
Object.defineProperty(Object.prototype, "extend", { enumerable: false, value: function(from) { var props = Object.getOwnPropertyNames(from); var dest = this; props.forEach(function(name) { if (name in dest) { var destination = Object.getOwnPropertyDescriptor(from, name); Object.defineProperty(dest, name, destination); } }); return this; } });
一旦你做到了这一点,你就可以做到:
var obj = { name: 'stack', finish: 'overflow' } var replacement = { name: 'stock' }; obj.extend(replacement);
我刚刚在这里写了一篇博文:http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
我今天需要合并对象,这个问题(和答案)对我帮助很大。我尝试了一些答案,但没有一个符合我的需要,所以我组合了一些答案并自己添加了一些东西,并提出了一个新的合并函数。这里是:
var merge = function() {
var obj = {},
i = 0,
il = arguments.length,
key;
for (; i < il; i++) {
for (key in arguments[i]) {
if (arguments[i].hasOwnProperty(key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
};
一些示例用法:
var t1 = {
key1: 1,
key2: "test",
key3: [5, 2, 76, 21]
};
var t2 = {
key1: {
ik1: "hello",
ik2: "world",
ik3: 3
}
};
var t3 = {
key2: 3,
key3: {
t1: 1,
t2: 2,
t3: {
a1: 1,
a2: 3,
a4: [21, 3, 42, "asd"]
}
}
};
console.log(merge(t1, t2));
console.log(merge(t1, t3));
console.log(merge(t2, t3));
console.log(merge(t1, t2, t3));
console.log(merge({}, t1, { key1: 1 }));
浅的
var obj = { name : "Jacob" , address : ["America"] }
var obj2 = { name : "Shaun" , address : ["Honk Kong"] }
var merged = Object.assign({} , obj,obj2 ); //shallow merge
obj2.address[0] = "new city"
result.地址[0]更改为“新城”,即合并对象也更改。这就是浅层合并的问题。
deep
var obj = { name : "Jacob" , address : ["America"] }
var obj2 = { name : "Shaun" , address : ["Honk Kong"] }
var result = Object.assign({} , JSON.parse(JSON.stringify(obj)),JSON.parse(JSON.stringify(obj2)) )
obj2.address[0] = "new city"
result.address[0]未更改
使用以下助手,可以将两个对象合并为一个新对象:
function extend(obj, src) {
for (var key in src) {
if (src.hasOwnProperty(key)) obj[key] = src[key];
}
return obj;
}
// example
var a = { foo: true }, b = { bar: false };
var c = extend(a, b);
console.log(c);
// { foo: true, bar: false }
当将选项dict与函数或插件中的默认设置合并时,这通常很有用。
如果不需要支持IE 8,您可以使用Object.keys来实现相同的功能:
function extend(obj, src) {
Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
return obj;
}
这涉及的代码稍微少一点,速度也快一点。
ES5兼容的原生单内胆:
var merged = [obj1, obj2].reduce(function(a, o) { for(k in o) a[k] = o[k]; return a; }, {})