Be careful when copying objects in Javascript
If you are going for a Javascript interview or going to start working in Javascript, you need to know how to copy objects in Javascript.
First, know that Javascript objects are stored by reference. Here’s an illustration:
const cat = {
cry: 'meow'
}
const dog = cat
dog.cry = 'woof'
console.log(cat.cry) // woofWhen dog is assigned to cat, we are just assigning the memory address of cat to dog. This is why changing dog.cry also changes cat.cry. Both cat and dog are pointing to the same memory address.
So, how do we copy objects?
Shallow copy
Here are two quick ways to shallow copy and object.
Spread Syntax
const cat = {
cry: 'meow'
}
const dog = { ...cat }Object.assign
const cat = {
cry: 'meow'
}
const dog = Object.assign({}, cat)But hold on, shallow copy only copies the first “layer” of the object. This means that any properties that are a reference to an object will give us the same problem we had in the first place.
Here’s what I mean:
const cat = {
cry: 'meow',
owner: {
name: 'Dan'
}
}
const dog = { ...cat }
dog.owner.name = 'Jake'
console.log(cat.owner.name) // Jakecat.owner is an object, with its own memory address. By shallow copying cat, dog.owner shared the same memory address as cat.owner. This caused the problem where modifying dog.owner would also modify cat.owner. Yikes!
Let’s look at how we can do a deep copy.
Deep copy
Here’s how you can do a deep copy.
JSON.stringify and JSON.parse
const cat = {
cry: 'meow',
owner: {
name: 'Dan'
}
}
const dog = JSON.parse(JSON.stringify(cat))JSON.stringify will convert the entire cat object into a string. And JSON.parse will convert that string back into an object, which means there aren’t any shared memory references with the original cat object!
However, there are some limitations:
Dateobjects are stringified and aren’t automatically converted back toDateobjectsundefinedproperties are lostInfinityis incorrectly set tonull- RegEx properties are lost
If you need to use any of the above, consider using a utility library!
Lodash
Lodash is an awesome Javascript library full of utility functions. It is well-tested and used in many production modules!
It comes with the .clone() and .cloneDeep() function, which can do a shallow or a deep copy of an object (as the name says, duh).
const _ = require('lodash')
const cat = {
cry: 'meow',
owner: {
name: 'Dan'
}
}
const dog = _.cloneDeep(cat)That’s all. Hope you learned something. Happy coding! :)