我需要能够在运行时合并两个(非常简单)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
是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。
当前回答
在MooTools中,有Object.merge():
Object.merge(obj1, obj2);
其他回答
ECMAScript 2018标准方法
您可以使用对象扩散:
let merged = {...obj1, ...obj2};
merged现在是obj1和obj2的并集。obj2中的财产将覆盖obj1中的属性。
/** There's no limit to the number of objects you can merge.
* Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};
这里还有此语法的MDN文档。如果您正在使用babel,则需要@babel/plugin提议对象rest spread插件才能工作(该插件包含在ES2018中的@babel/preset-env中)。
ECMAScript 2015(ES6)标准方法
/* For the case in question, you would do: */
Object.assign(obj1, obj2);
/** There's no limit to the number of objects you can merge.
* All objects get merged into the first object.
* Only the object in the first argument is mutated and returned.
* Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);
(参见MDN JavaScript参考)
ES5及更早版本的方法
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
请注意,这将简单地将obj2的所有属性添加到obj1中,如果您仍然希望使用未修改的obj1,那么这可能不是您想要的。
如果你使用的是一个在你的原型上到处都是垃圾的框架,那么你必须通过hasOwnProperty这样的检查来获得更高的效率,但这段代码在99%的情况下都是有效的。
示例函数:
/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
*/
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
哇!这是我在多个页面上看到的第一篇StackOverflow文章。为添加另一个“答案”表示歉意
ES5及更早版本
此方法适用于ES5及更早版本-有许多其他答案可用于ES6。
我没有看到任何利用arguments属性的“深层”对象合并。以下是我的答案-紧凑和递归,允许传递无限的对象参数:
function extend() {
for (var o = {}, i = 0; i < arguments.length; i++) {
// Uncomment to skip arguments that are not objects (to prevent errors)
// if (arguments[i].constructor !== Object) continue;
for (var k in arguments[i]) {
if (arguments[i].hasOwnProperty(k)) {
o[k] = arguments[i][k].constructor === Object
? extend(o[k] || {}, arguments[i][k])
: arguments[i][k];
}
}
}
return o;
}
实例
/***扩展对象*/函数扩展(){对于(var o={},i=0;i<arguments.length;i++){for(自变量[i]中的var k){if(参数[i].hasOwnProperty(k)){o[k]=参数[i][k].构造函数==对象? extend(o[k]||{},参数[i][k]):参数[i][k];}}}返回o;}/***示例*/document.write(JSON.stringify(扩展({api:1,参数:{查询:“hello”}}, {参数:{查询:'there'}})));//输出{“api”:1,“params”:{“query”:“there”}
这个答案现在只是沧海一粟。。。
浅的
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]未更改
对于不太复杂的对象,可以使用JSON:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'chevy'}
var objMerge;
objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);
// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}
objMerge = objMerge.replace(/\}\{/, ","); // \_ replace with comma for valid JSON
objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/
请注意,在此示例中,“}{”不能出现在字符串中!
有三种方法可以做到这一点:-
方法1:-
// using spread ...
let obj1 = {
...obj2
};
方法2:-
// using Object.assign() method
let obj1 = Object.assign({}, obj2);
方法3:-
// using JSON
let obj1 = JSON.parse(JSON.stringify(obj2));