Copying and Object in JavaScript

David Kerr
Dec 9, 2017 · 2 min read

Up until yesterday, I thought the correct way to copy an object in JavaScript is using Object.assign().

let obj = {a: 1, b: 2, c: 3};
let newObj = Object.assign({}, obj);
// assign new value to a in newObj
newObj.a = 4;
// old obj should be unaffected, no reference error
obj
// returns original obj {a: 1, b: 2, c: 3}

A reference error is created when you set one variable equal to another, changes to one can affect another. By assigning properties from our original object we can avoid this issue altogether, right? Apparently not.

You have reference issues with any deep nested properties.

let obj = {a: 1, b: 2, c: {d: 4} };
let newObj = Object.assign({}, obj);
// reassign new value to c.d
newObj.c.d = 5;
// obd obj has been changed with newObj
obj
// returns {a: 1, b: 2, c: {d: 5} }
// what I had expected {a: 1, b: 2, c: {d: 4} }

So there it is, reference errors copying any object with deep nested properties.

Yesterday I was chasing down a strange bug in a react-redux application. Something was changing my redux store even though that particular reducer was never called. What had happened was as I set state in another reducer, I used Object.assign({}, obj) to (I thought) copy an object from another store. In reality, I as I changed an array nested with the copied object, the original object was affected as well.

My example was with an edit work flow, so if a user canceled the edit it would appear that the changes were saved (until the page is refreshed and the store is reset).

I can’t believe in (almost) 2018, with all the improvements made to make programming cleaner, that the best way to copy a JavaScript object is this:

let obj = {a: 1, b: 2, c: {d: 4}};
let newObj = JSON.parse(JSON.stringify(obj));
newObj.c.d = 100// original object c.d is unaffected
obj
// returns {a: 1, b: 2, c: {d: 4}}
newObj
// returns {a: 1, b: 2, c: {d: 100}}

But, that is how Mozilla recommends you deep clone an object. They even have a warning section about this shortcoming on Object.assign() in the mdn docs.

I hope this post helps someone else avoid wasting hours as I did.

David Kerr

Written by

software developer at canvas technology

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade