我需要能够在运行时合并两个(非常简单)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)
请参见合并(对象):对象。
其他回答
JSON兼容JavaScript对象的合并
我鼓励使用和利用不修改原始源代码的非破坏性方法,“Object.assign”是一种破坏性的方法,而且它也不太适合生产,因为它在早期浏览器上停止工作,而且你没有办法用其他方法对它进行干净的修补。
无论采用何种解决方案,合并JS对象都将永远无法实现或不完整。但是,合并JSON兼容的兼容对象离能够编写一段简单且可移植的代码只有一步之遥。该代码是一种非破坏性方法,将一系列JS对象合并到一个返回的主对象中,该主对象包含所有唯一的属性名及其对应的值,这些属性名合成在一个主对象中用于预期目的。
考虑到MSIE8是第一个为JSON对象添加本地支持的浏览器,这是一种极大的解脱,重用现有技术始终是一个受欢迎的机会。
将代码限制为JSON兼容的标准对象,与其说是限制,不如说是优势,因为这些对象也可以通过互联网传输。当然,对于那些想要更深入的向后兼容性的人来说,总是有一个json插件。,其方法可以很容易地分配给外部代码中的JSON变量,而无需修改或重写正在使用的方法。
function Merge( ){
var a = [].slice.call( arguments ), i = 0;
while( a[i] )a[i] = JSON.stringify( a[i++] ).slice( 1,-1 );
return JSON.parse( "{"+ a.join() +"}" );
}
(当然,人们总是可以给它取一个更有意义的名字,我还没有决定;应该把它命名为JSONmerge)
用例:
var master = Merge( obj1, obj2, obj3, ...objn );
现在,与Object.assign相反,这将使所有对象保持不变,并保持其原始状态(以防您做错了什么,需要重新排序合并对象,或者在再次合并之前能够将它们单独用于其他操作)。
Merge参数的数量也仅受参数长度限制[这是巨大的]的限制。本机支持的JSON parse/stringify已经进行了机器优化,这意味着:它应该比任何脚本形式的JS循环都快。对给定参数的迭代是使用while完成的,while被证明是JS中最快的循环。
简单地提一下我们已经知道的事实,即唯一对象标签(键)的重复财产将被包含相同键标签的后一个对象覆盖,这并不有害,这意味着您可以通过简单地对参数列表进行排序或重新排序来控制哪个属性将取代前一个属性。以及获得一个干净且更新的主对象而无重复作为最终输出的好处。
;var obj1={a:1},obj2={b:2},obj3={c:3};函数合并(){var a=[].slice.call(参数),i=0;而(a[i])a[i]=JSON.stringify(a[i++]).slice(1,-1);return JSON.parse(“{”+a.join()+“}”);};var master=合并(obj1、obj2、obj3);console.log(JSON.stringify(master));
对于不太复杂的对象,可以使用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_/
请注意,在此示例中,“}{”不能出现在字符串中!
我使用Object.create()来保持默认设置(使用__proto__或Object.getPrototypeOf())。
function myPlugin( settings ){
var defaults = {
"keyName": [ "string 1", "string 2" ]
}
var options = Object.create( defaults );
for (var key in settings) { options[key] = settings[key]; }
}
myPlugin( { "keyName": ["string 3", "string 4" ] } );
这样我以后就可以一直使用“concat()”或“push()”。
var newArray = options['keyName'].concat( options.__proto__['keyName'] );
注意:为了避免重复,需要在连接之前进行hasOwnProperty检查。
Harmony ECMAScript 2015(ES6)指定了将执行此操作的Object.assign。
Object.assign(obj1, obj2);
当前的浏览器支持越来越好,但如果您正在为没有支持的浏览器开发,则可以使用polyfill。
gossi对David Coallier方法的扩展:
检查这两行:
from = arguments[i];
Object.getOwnPropertyNames(from).forEach(function (name) {
需要针对空对象检查“from”。。。例如,如果合并以前在服务器上创建的来自Ajax响应的对象,则对象属性的值可以为“null”,在这种情况下,上述代码会生成一个错误消息:
“from”不是有效对象
因此,例如,将“…Object.getOwnPropertyNames(from).forEach…”函数包装为“if(from!=null){…}”将防止发生该错误。