简体   繁体   中英

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?

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.

I highly recommend jQuery's extend method, as it will provide a full browser support.

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:

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

See the jQuery's documentation for more info: jQuery Docs for Extend method

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

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

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

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.

Note that dojo.mixin operates in the opposite direction to what you hinted at in your example.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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