简体   繁体   English

在javascript中合并两个对象文字

[英]Merge two object literals in javascript

I have two object literals: 我有两个对象文字:

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

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

Need a merging function like this: 需要这样的合并功能:

dog = someMergingFunction(animal, dog);

That produces: 这产生:

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

One of the object literals has to replace identical properties. 其中一个对象文字必须替换相同的属性。

How do I do this in Javascript? 我如何在Javascript中执行此操作?

The following should work: 以下应该有效:

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

If both objects have the same property, the value in obj2 takes precedence. 如果两个对象具有相同的属性,则obj2的值优先。

I highly recommend jQuery's extend method, as it will provide a full browser support. 我强烈推荐使用jQuery的extend方法,因为它将提供完整的浏览器支持。

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

Remember that the first argument is the target. 请记住,第一个参数是目标。 The good point about usage of extend is that by following code, you can make it extend recursively: 关于extend的使用的好处是,通过以下代码,您可以使其递归扩展:

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

See the jQuery's documentation for more info: jQuery Docs for Extend method 有关更多信息,请参阅jQuery的文档: 用于Extend方法的jQuery Docs

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

I recommend using underscore.js as it contains functionality for this and a whole load of related things: 我建议使用underscore.js因为它包含了这个功能和一大堆相关的东西:

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

http://underscorejs.org/#extend http://underscorejs.org/#extend

Assume properties of the first parameter will override properties of the 2nd parameter (as your example), this will do: 假设第一个参数的属性将覆盖第二个参数的属性(作为示例),这将执行:

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

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

This might be swatting a fly with a buick, but you might be interested to see how Dojo does basically the same thing in dojo.mixin (at least if I understood the question correctly). 这可能是用buick dojo.mixin打苍蝇,但你可能有兴趣看看Dojo在dojo.mixin如何做同样的事情(至少如果我正确地理解了这个问题)。

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

The basic functionality is in dojo._mixin , while dojo.mixin makes it work iteratively for multiple objects progressively in one shot. 基本功能在dojo._mixin ,而dojo.mixin使其可以一次性逐步迭代地处理多个对象。

Note that dojo.mixin operates in the opposite direction to what you hinted at in your example. 请注意, dojo.mixin操作方向与您在示例中所暗示的方向相反。

What about spread syntax ? 传播语法怎么样?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax 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 } 

There are some good suggestions here. 这里有一些很好的建议。

I know this is a really old question, but for future visitors looking for a slightly more flexible solution, I have a similar function that I wrote that accepts any number of objects in an array and merges them all together and returns a single object with the properties of all of the object literals in the array. 我知道这是一个非常古老的问题,但是对于寻找更灵活的解决方案的未来访问者,我有一个类似的函数,我写的接受数组中的任意数量的对象并将它们合并在一起并返回一个对象与数组中所有对象文字的属性。

Note: the order of precedence is determined by the array. 注意:优先顺序由数组决定。 Each subsequent object will overwrite identical properties if they exist in previous objects. 如果先前的对象中存在相同的属性,则每个后续对象都将覆盖它们。 Otherwise, new properties are simply added to the single object that is returned. 否则,只需将新属性添加到返回的单个对象中。

I hope this will help future visitors to this question. 我希望这将有助于未来的访问者提出这个问题。 Here's the function, very short and sweet: 这是功能,非常简短和甜蜜:

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

You can use it like this: 你可以像这样使用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM