在javascript中合并两个对象文字

时间:2010-12-01 02:04:31

标签: javascript

我有两个对象文字:

var animal = {
    eat: function() {
        console.log("eating...");
    }
}

var dog = {
    eat: "this has to be replaced when merged",
    nrOfLegs: 4
}

需要这样的合并功能:

dog = someMergingFunction(animal, dog);

产生:

{
    eat: function() {
        console.log("eating...");
    },
    nrOfLegs: 4
}

其中一个对象文字必须替换相同的属性。

如何在Javascript中执行此操作?

9 个答案:

答案 0 :(得分:12)

以下内容应该有效:

function merge(obj1, obj2) {
  var obj = {};

  for (var x in obj1)
    if (obj1.hasOwnProperty(x))
      obj[x] = obj1[x];

  for (var x in obj2)
    if (obj2.hasOwnProperty(x))
      obj[x] = obj2[x];

  return obj;
}

如果两个对象具有相同的属性,则obj2中的值优先。

答案 1 :(得分:6)

我强烈推荐使用jQuery的extend方法,因为它将提供完整的浏览器支持。

var object = $.extend({}, object1, object2, ..., objectN);

请记住,第一个参数是目标。关于extend的使用的好处是,通过以下代码,您可以使其递归扩展:

var object = $.extend(object, object1, object2, ..., objectN);

有关详细信息,请参阅jQuery的文档:jQuery Docs for Extend method

答案 2 :(得分:5)

// usage merged = someMergingFunction(a, b, c, d, ...)
// keys in earlier args override keys in later args.
// someMergingFunction({foo:"bar"}, {foo:"baz"})
//  ==> {foo:"bar"}
function someMergingFunction () {
  var o = {}
  for (var i = arguments.length - 1; i >= 0; i --) {
    var s = arguments[i]
    for (var k in s) o[k] = s[k]
  }
  return o
}

答案 3 :(得分:3)

假设第一个参数的属性将覆盖第二个参数的属性(作为示例),这样做:

function merge(obj1, obj2) {
    for(attr in obj1)
        obj2[attr]=obj1[attr];
    return obj2;
}

答案 4 :(得分:3)

我建议使用underscore.js,因为它包含此功能和一大堆相关内容:

_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}

http://underscorejs.org/#extend

答案 5 :(得分:2)

截至2017年,我会使用Object.assign(foo, bar)

答案 6 :(得分:1)

这可能是用buick拍打苍蝇,但你可能有兴趣看看Dojo在dojo.mixin中是如何做同样的事情(至少如果我理解正确的话)。

https://github.com/dojo/dojo/blob/0dddc5a0bfe3708e4ba829434602da51cbb041b7/_base/_loader/bootstrap.js#L277-366

基本功能在dojo._mixin,而dojo.mixin使其可以一次性逐步迭代地处理多个对象。

请注意,dojo.mixin的操作方向与您在示例中所暗示的方向相反。

答案 7 :(得分:1)

那传播语法呢?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

var obj1 = { foo: 'bar', x: 42 };

var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 } 

答案 8 :(得分:0)

这里有一些很好的建议。

我知道这是一个非常古老的问题,但对于寻找更灵活的解决方案的未来访问者,我有一个类似的功能,我写的接受数组中的任意数量的对象并合并它们全部在一起并返回一个具有数组中所有对象文字属性的对象。

注意:优先顺序由数组决定。如果先前的对象中存在相同的属性,则每个后续对象都将覆盖它们。否则,只需将新属性添加到返回的单个对象中。

我希望这将有助于未来的访问者提出这个问题。这是功能,非常简短和甜蜜:

var mergeObjects = function (objectsArray) {
    var result = {};
    for (var i = 0; i < objectsArray.length; i++) {
        for (var obj in objectsArray[i]) {
            if (objectsArray[i].hasOwnProperty(obj)) {
                result[obj] = objectsArray[i][obj];
            };
        };
    };
    return result;
};

你可以像这样使用它:

// Define the mergeObjects function
var mergeObjects = function (objectsArray) {
  var result = {};
  for (var i = 0; i < objectsArray.length; i++) {
    for (var obj in objectsArray[i]) {
      if (objectsArray[i].hasOwnProperty(obj)) {
        result[obj] = objectsArray[i][obj];
      };
    };
  };
  return result;
};


// Define some objects to merge, keeping one property consistent so you can
// see it overwrite the old ones
var obj1 = { test1: "test", overwrite: "overwrite1" };
var obj2 = { test2: "test2", overwrite: "overwrite2" };
var obj3 = { test3: "test3", overwrite: "overwrite3" };

// Merge the objects
var newObject = mergeObjects([obj1, obj2, obj3]);

// Test the output
for (var obj in newObject){
  if (newObject.hasOwnProperty(obj)){
    document.body.innerHTML += newObject[obj] + "<br />";  
  }
}