我需要能够在运行时合并两个(非常简单)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
是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。
当前回答
在Ext JS 4中,可以如下所示:
var mergedObject = Ext.Object.merge(object1, object2)
// Or shorter:
var mergedObject2 = Ext.merge(object1, object2)
请参见合并(对象):对象。
其他回答
我在谷歌上搜索了合并对象财产的代码,结果出现在这里。然而,由于没有递归合并的代码,我自己编写了它。(也许jQuery扩展是递归的BTW?)无论如何,希望其他人也会发现它很有用。
(现在代码不使用Object.prototype:)
Code
/*
* Recursively merge properties of two objects
*/
function MergeRecursive(obj1, obj2) {
for (var p in obj2) {
try {
// Property in destination object set; update its value.
if ( obj2[p].constructor==Object ) {
obj1[p] = MergeRecursive(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
// Property in destination object not set; create it and set its value.
obj1[p] = obj2[p];
}
}
return obj1;
}
一个例子
o1 = { a : 1,
b : 2,
c : {
ca : 1,
cb : 2,
cc : {
cca : 100,
ccb : 200 } } };
o2 = { a : 10,
c : {
ca : 10,
cb : 20,
cc : {
cca : 101,
ccb : 202 } } };
o3 = MergeRecursive(o1, o2);
生成类似o3的对象
o3 = { a : 10,
b : 2,
c : {
ca : 10,
cb : 20,
cc : {
cca : 101,
ccb : 202 } } };
function extend()
{
var o = {};
for (var i in arguments)
{
var s = arguments[i];
for (var i in s)
{
o[i] = s[i];
}
}
return o;
}
gossi对David Coallier方法的扩展:
检查这两行:
from = arguments[i];
Object.getOwnPropertyNames(from).forEach(function (name) {
需要针对空对象检查“from”。。。例如,如果合并以前在服务器上创建的来自Ajax响应的对象,则对象属性的值可以为“null”,在这种情况下,上述代码会生成一个错误消息:
“from”不是有效对象
因此,例如,将“…Object.getOwnPropertyNames(from).forEach…”函数包装为“if(from!=null){…}”将防止发生该错误。
原型中的正确实现应该如下所示:
var obj1 = {food: 'pizza', car: 'ford'}
var obj2 = {animal: 'dog'}
obj1 = Object.extend(obj1, obj2);
顺便说一句,你们正在做的是覆盖财产,而不是合并。。。
这就是JavaScript对象区域真正合并的方式:只有to对象中不是对象本身的键才会被from覆盖。其他一切都将被真正合并。当然,您可以将此行为更改为不覆盖任何存在的内容,例如仅当to[n]未定义时,等等…:
var realMerge = function (to, from) {
for (n in from) {
if (typeof to[n] != 'object') {
to[n] = from[n];
} else if (typeof from[n] == 'object') {
to[n] = realMerge(to[n], from[n]);
}
}
return to;
};
用法:
var merged = realMerge(obj1, obj2);