Bloomsol Logo

Object.assign() gotchas

21st April, 2020

Object.assign() is a common way to create a new object and to copy all the properties. As per MDN this method copies all enumerable own properties from one or more source objects to a target object.

One of the most common use cases, is to create a new object from an existing object like below:

const obj = { a: 5, b: 10 }
const target = Object.assign({}, obj)
console.log(target)
// expected output: Object { a: 5, b: 10 }

While it looks to be perfect, this creates a shallow copy for objects with nested properties. Any updates or changes to the target object also update the source.

const obj1 = { a: 5, b: 10 }
const obj2 = { obj1, c: 15 }
const target = Object.assign({}, obj2)
console.log(target)
// output: Object { obj1: { a: 5, b: 10 }, c: 15 }

target.obj1.a = 42
console.log(obj1)
// expected output: Object { a: 5, b: 10 }
// output: Object { a: 42, b: 10 }

One way to avoid the previous gotcha is simply performing a deep copy. lodash library has a cloneDeep() method which is perfect for the previous scenario. The above example rewritten using lodash is as below:

const obj1 = { a: 5, b: 10 }
const obj2 = { obj1, c: 15 }
const target = _.cloneDeep(obj2)
console.log(target)
// output: Object { obj1: { a: 5, b: 10 }, c: 15 }

target.obj1.a = 42
console.log(obj1)
// output: Object { a: 5, b: 10 }

Don't forget to checkout Lodash docs for more handy methods for cloning.

Bloomsol Pty Ltd © 2022