我需要能够在运行时合并两个(非常简单)JavaScript对象。例如,我想:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。


当前回答

使用此

var t=merge({test:123},{mysecondTest:{blub:{test2:‘string‘},args:{‘test‘:2}})控制台日志(t);函数合并(…args){return Object.assign({},…args);}

其他回答

哇!这是我在多个页面上看到的第一篇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”}


这个答案现在只是沧海一粟。。。

函数扩展(o,o1,o2){如果(!(o instanceof Object))o={};副本(o,o1);如果(o2)副本(o,o2)函数isObject(obj){var type=Object.protype.toString.call(obj);return obj===对象(obj)&&type!='[object Array]'&&type!='[object函数]';};功能副本(a,b){//将o2复制到ofor(b中的var键)if(b.hasOwnProperty(键)){if(isObject(b[key])){if(!isObject(a[key]))a[key]=Object.assign({},b[key]);其他副本(a[key],b[key])}其他的a[key]=b[key];}}返回o;};变量o1={a:{foo:1},b:1},o2={a:{bar:2},b:[1],c:()=>{}},newMerged=扩展({},o1,o2);console.log(newMerged)控制台日志(o1)控制台日志(o2)

原型中的正确实现应该如下所示:

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);

如果有人正在使用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'