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

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

obj1.merge(obj2);

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

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


当前回答

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

其他回答

您可以通过以下方法合并对象

var obj1={food:‘pizza‘,car:‘ford‘};var obj2={animal:‘dog‘};var result=合并对象([obj1,obj2]);console.log(结果);document.write(“result:<pre>”+JSON.stringify(result,0,3)+“</pre>”);函数mergeObjects(objectArray){if(objectArray.length){var b=“”,i=-1;while(objectArray[++i]){var str=JSON.stringify(objectArray[i]);b+=字符串长度(1,字符串长度-1);如果(objectArray[i+1])b+=“,”;}返回JSON.parse(“{”+b+“}”);}返回{};}

这是我的刺

支持深度合并不改变参数采用任意数量的参数不扩展对象原型不依赖于其他库(jQuery、MooTools、Undercore.js等)包括检查hasOwnProperty短:)/*递归合并财产并返回新对象对象1&lt;-对象2[&lt;-…]*/函数合并(){变量dst={},srcp,args=[].splice.call(参数,0);while(参数长度>0){src=参数拼接(0,1)[0];if(toString.call(src)=='[object object]'){for(src中的p){if(src.hasOwnProperty(p)){if(toString.call(src[p])=='[object object]'){dst[p]=合并(dst[p]||{},src[p]);}其他{dst[p]=src[p];}}}}}返回dst;}

例子:

a = {
    "p1": "p1a",
    "p2": [
        "a",
        "b",
        "c"
    ],
    "p3": true,
    "p5": null,
    "p6": {
        "p61": "p61a",
        "p62": "p62a",
        "p63": [
            "aa",
            "bb",
            "cc"
        ],
        "p64": {
            "p641": "p641a"
        }
    }
};

b = {
    "p1": "p1b",
    "p2": [
        "d",
        "e",
        "f"
    ],
    "p3": false,
    "p4": true,
    "p6": {
        "p61": "p61b",
        "p64": {
            "p642": "p642b"
        }
    }
};

c = {
    "p1": "p1c",
    "p3": null,
    "p6": {
        "p62": "p62c",
        "p64": {
            "p643": "p641c"
        }
    }
};

d = merge(a, b, c);


/*
    d = {
        "p1": "p1c",
        "p2": [
            "d",
            "e",
            "f"
        ],
        "p3": null,
        "p5": null,
        "p6": {
            "p61": "p61b",
            "p62": "p62c",
            "p63": [
                "aa",
                "bb",
                "cc"
            ],
            "p64": {
                "p641": "p641a",
                "p642": "p642b",
                "p643": "p641c"
            }
        },
        "p4": true
    };
*/

对于不太复杂的对象,可以使用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.extend = function(destination,source) {
    for (var property in source)
        destination[property] = source[property];
    return destination;
}

obj1.extend(obj2)将执行您想要的操作。

应修改给定的解决方案以检查for中的source.hasOwnProperty(属性)。。在赋值之前的循环中-否则,您最终会复制整个原型链的财产,这是很少需要的。。。