How to duplicate object properties in another object?

Javascript

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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.

Solution 3 - Javascript

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 4 - Javascript

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 for-in loop isn't enough; you need hasOwnProperty. See http://bonsaiden.github.com/JavaScript-Garden/#object.forinloop for a detailed explanation of why.

Solution 5 - Javascript

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.

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 - Javascript

One can use Object.assign to combine objects. It will combine and overrides the common property from right to left i.e, same property in left will be overridden by right.

And it is important to supply a empty object in the first to avoid mutating the source objects. The source objects should be left clean as Object.assign() by itself returns a new object.

Hope this helps!

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

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

var finalObject = Object.assign({}, firstObject, secondObject)

console.log(finalObject)

Solution 7 - Javascript

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

Solution 8 - Javascript

Improvement of kingPuppy idea and OP idea (shallow copy) - I only add 3 dots to OP "example" :)

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

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

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

console.log(secondObject);

Solution 9 - Javascript

This should work, tested here.

var secondObject = {
    firstObject: JSON.parse(JSON.stringify(firstObject)),
    key3 : 'value3',
    key4 : 'value4'
};

Note: this will not copy methods of firstObject
Note 2: for use in older browsers, you'll need a json parser
Note 3: assigning by reference is a viable option, especially if firstObject contains methods. Adjusted the given jsfiddle example accordingly

Solution 10 - Javascript

Use the property spread notation. It was added in ES2018 (spread for arrays/iterables was earlier, ES2015), {...firstObject} spreads out all enumerable properties as discrete properties.

let secondObject = {
      ...firstObject,
      key3 : 'value3',
      key4 : 'value4'
    }

Solution 11 - Javascript

Unfortunately, you cannot put a reference to a variable in an object like that. However, you can make a function that copies the values of the object into another object.

function extend( obj1, obj2 ) {
    for ( var i in obj2 ) {
        obj1[i] = obj2[i];
    }
    return obj1;
}

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

var secondObject = extend({
    key3: "value3",
    key4: "value4"
}, firstObject );

Solution 12 - Javascript

If you wanted to grab only the properties that exist in the second object, you can use Object.keys to grab the properties of the first object, you can do two methods:

A.) map to assign the first object's properties to the second object using side effects:

var a = {a:100, b:9000, c:300};
var b = {b:-1};

Object.keys(a).map(function(key, index) {
	if (typeof b[key] !== 'undefined') {
		console.log(key);
		b[key] = a[key];	
	}
});

B.) or reduce to create a new object and assign it to the second object. Be aware that this method replaces other properties the second object might have before that which did not match the first object:

var a = {a:100, b:9000, c:300};
var b = {b:-1, d:-1}; // d will be gone

b = Object.keys(a).reduce(function(result, current) {
	if (typeof b[current] !== 'undefined') {
		result[current] = a[current];	
	}
    return result;
}, {});

Solution 13 - Javascript

For the record, this can now also be done with

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

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

Solution 14 - Javascript

Object.assign or destructring may bite you seriously due to the fact that only top-level properties are copied as values.

All the nested properties will be copied as references and would keep the references to the original object's properties. If your object is flat, that is ok. But if not, these soultions are rarely applicable.

For simplest and effective one-liner I would recommend deepmerge package that is free from that drawback.

const newObject = deepmerge({}, oldObjectWithNestedProperties);

This would give you the completelly detached and independent newObject copy of your oldObjectWithNestedProperties.

Solution 15 - Javascript

I would rather use firstObject as prototype of secondObject, and add property descriptor:

var secondObject = Object.create(firstObject, {
      key3: {value: "value3", writable: true, configurable: true, enumerable: true},
      key4: {value: "value4", writable: true, configurable: true, enumerable: true}
      });

It's certainly not one-liner, but it gives you more control. If you are interested in property descriptors, I suggest to read this article: http://patrickdelancy.com/2012/09/property-descriptors-in-javascript/#comment-2062 and MDN page https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

You can also just assign values and omit the descriptors and make it a bit shorter:

var secondObject = Object.create(firstObject, {
      key3: {value: "value3"}
      key4: {value: "value4"}
  });

Compatibility: ECMAScript 5, so IE9+

Solution 16 - Javascript

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

var secondObject = {
     key3: "value3",
     key4: "value4"
     copy: function(firstObject){
           this.key1 = firstObject.key1;
           this.key2 = firstObject.key2;
     }
 };

Using the follwing method will copy the properties

secondObject.copy(firstObject)

I am very new to javascript, but found this working. A little too long I guess, but it works.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIgor PopovView Question on Stackoverflow
Solution 1 - JavascriptMichael Krelin - hackerView Answer on Stackoverflow
Solution 2 - JavascriptThe DIMM ReaperView Answer on Stackoverflow
Solution 3 - JavascriptkingPuppyView Answer on Stackoverflow
Solution 4 - JavascriptBen LeeView Answer on Stackoverflow
Solution 5 - JavascriptbardzusnyView Answer on Stackoverflow
Solution 6 - JavascriptPranesh RaviView Answer on Stackoverflow
Solution 7 - JavascriptNijikokunView Answer on Stackoverflow
Solution 8 - JavascriptKamil KiełczewskiView Answer on Stackoverflow
Solution 9 - JavascriptKooiIncView Answer on Stackoverflow
Solution 10 - JavascriptAnthony AwuleyView Answer on Stackoverflow
Solution 11 - JavascriptWillView Answer on Stackoverflow
Solution 12 - JavascriptapebeastView Answer on Stackoverflow
Solution 13 - JavascriptserguitusView Answer on Stackoverflow
Solution 14 - JavascriptValentine ShiView Answer on Stackoverflow
Solution 15 - JavascriptAhmet CetinView Answer on Stackoverflow
Solution 16 - JavascriptSindhu TirthView Answer on Stackoverflow