我需要能够在运行时合并两个(非常简单)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
是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。
当前回答
另一种方法:
function concat_collection(obj1, obj2) {
var i;
var arr = new Array();
var len1 = obj1.length;
for (i=0; i<len1; i++) {
arr.push(obj1[i]);
}
var len2 = obj2.length;
for (i=0; i<len2; i++) {
arr.push(obj2[i]);
}
return arr;
}
var ELEMENTS = concat_collection(A,B);
for(var i = 0; i < ELEMENTS.length; i++) {
alert(ELEMENTS[i].value);
}
其他回答
如果有人正在使用Google闭包库:
goog.require('goog.object');
var a = {'a': 1, 'b': 2};
var b = {'b': 3, 'c': 4};
goog.object.extend(a, b);
// Now object a == {'a': 1, 'b': 3, 'c': 4};
数组存在类似的助手函数:
var a = [1, 2];
var b = [3, 4];
goog.array.extend(a, b); // Extends array 'a'
goog.array.concat(a, b); // Returns concatenation of array 'a' and 'b'
如果您使用的是DojoToolkit,那么合并两个对象的最佳方法是使用mixin。
下面是DojoToolkit mixin的示例:
// Dojo 1.7+ (AMD)
require(["dojo/_base/lang"], function(lang){
var a = { b:"c", d:"e" };
lang.mixin(a, { d:"f", g:"h" });
console.log(a); // b:c, d:f, g:h
});
// Dojo < 1.7
var a = { b:"c", d:"e" };
dojo.mixin(a, { d:"f", g:"h" });
console.log(a); // b:c, d:f, g:h
有关详细信息,请混合。
浅的
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]未更改
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;
}
您可以使用对象排列语法来实现这一点。这是ES2018及以后的一部分。
constobj1={food:“pizza”,car:“ford”};const obj2={animal:“狗”};常量obj3={…obj1,…obj2};console.log(obj3);