Native way to merge objects in Javascript

Solution 1:

My answer to this will be disappointing, but still:

no

The reason for this is simple: Mr Resig's implementation of merge (or "extend" as it's called for objects) in jQuery is doing a loop, just like the one in your question. You can look at it here. And I dare say that if John Resig hasn't found a clever build-in way to do it, then the mere mortals of stackoverflow won't either :)

Solution 2:

Using ES6 (ES2015) you can use Object.assign method:

var x = {a:1, b:2};
var y = {c:3, d:4};
var z = Object.assign({},x,y);

Using ES7 (ES2016, Chrome 60+ or Babel) you can use Object spread operator:

var x = {a:1, b:2};
var y = {c:3, d:4}; 
var z = {...x, ...y};

Solution 3:

The million dollar question! I've tried doing this numerous ways, and the loop way described above always seemed the dirtiest. ES6's Object.setPrototypeOf() allows you to delegate a "property override" object to a "default properties" object, pretty much accomplishing what you're trying to do, but using Object.setPrototypeOf() has some serious implications, like disabling the browser's compiler optimizations for the whole script.

Also, in both the loop solution and the Object.setPrototypeOf() solution, you are left with a situation where the "property override" object can mutate the "default properties" object:

defaultObj = {
    a: [1, 2]
}
...
overrideObj = {
    b: 3
}
Object.setPrototypeOf(overrideObj, defaultObj);
console.log(overrideObj); // {a: [1, 2], b: 3}
// Great!
...
overrideObj.a.push(4);
console.log(defaultObj); // {a: [1, 2, 4]}
// Uh-oh.

You might think this is not a problem, but let's say you're using this object as configuration for a 3rd party lib. You are now handing the control of your default object and everything referenced in it to the 3rd party lib.

A better solution might be to use JSON.stringify and JSON.parse to copy and combine the objects. Here's a Gist with the example: https://gist.github.com/spikesagal/6f7822466887f19b9c65

HTH

Solution 4:

Not that I know of, no. Also, you'll want to write your merge method like this:

function mergeInto(o1, o2) {
  if (o1 == null || o2 == null)
    return o1;

  for (var key in o2)
    if (o2.hasOwnProperty(key))
      o1[key] = o2[key];

  return o1;
}