How to duplicate object properties in another object?

How to duplicate object properties in another object?

Given the object:
var firstObject = {
key1 : ‘value1’,
key2 : ‘value2’
};

how can I copy the properties inside another object (secondObject) like this:
var secondObject = {
key1 : ‘value1’,
key2 : ‘value2’,
key3 : ‘value3’,
key4 : ‘value4’
};

using a reference to the firstObject? Something like this:
var secondObject = {
firstObject,
key3 : ‘value3’,
key4 : ‘value4’
};

(this doesn’t work… I put it just to show in big lines how I would like to structure the code).
Is a solution possible without using any JavaScript frameworks?

Solutions/Answers:

Solution 1:

for(var k in firstObject) secondObject[k]=firstObject[k];

Solution 2:

Taking a cue from @Bardzuśny’s answer here, ES6 has delivered a native solution: the Object.assign() function!

Usage is simple:

Object.assign(secondObject, firstObject);

That’s it!

Support right now is obviously poor; only Firefox (34+) supports it out-of-the-box, while Chrome (45+) and Opera (32+) require the ‘experimental flag’ to be set.

Support is improving, with the lastest versions of Chrome, Firefox, Opera, Safari and Edge supporting it (IE notably has no support.) Transpilers are available as well, like Babel and Traceur. See here for more details.

Related:  How do I change an HTML selected option using JavaScript?

Solution 3:

Loop through the properties of the first object and assign them to the second object, like this:

var firstObject = {
    key1 : 'value1',
    key2 : 'value2'
};

var secondObject = {
    key3 : 'value3',
    key4 : 'value4'
};

for (var prop in firstObject) {
    if (firstObject.hasOwnProperty(prop)) {
        secondObject[prop] = firstObject[prop];
    }
}

The forin loop isn’t enough; you need hasOwnProperty. See http://bonsaiden.github.com/JavaScript-Garden/#object.forinloop for a detailed explanation of why.

Solution 4:

Per ES6 – Spread syntax:

You can simply use:

const thirdObject = {
   ...firstObject,
   ...secondObject   
}

This avoids problems of passing these objects by reference.

Additionally it takes care of objects that have deep nesting.

Solution 5:

Playing the necromancer here, because ES5 brought us Object.keys(), with potential to save us from all these .hasOwnProperty() checks.

Object.keys(firstObject).forEach(function(key) {
  secondObject[key] = firstObject[key];
});

Or, wrapping it into a function (limited “copy” of lodash _.assign()):

function assign(object, source) {
  Object.keys(source).forEach(function(key) {
    object[key] = source[key];
  });
}

assign(secondObject, firstObject); // assign firstObject properties to secondObject

Object.keys() is relatively new method, most notably: not available in IE < 9. The same actually goes for .forEach() array method, which I used in place of regular for loop.

Related:  Convert an array of objects to array of the objects' values

Luckily, there is es5-shim available for these ancient browsers, which will polyfill many ES5 features (including those two).

(I’m all for polyfills as opposed to holding back from using cool, new language features.)

Solution 6:

Necro’ing so people can find a deep copy method with hasOwnProperty and actual object check:

var extend = function (original, context, key) {
  for (key in context)
    if (context.hasOwnProperty(key))
      if (Object.prototype.toString.call(context[key]) === '[object Object]')
        original[key] = extend(original[key] || {}, context[key]);
      else
        original[key] = context[key];
  return original;
};