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) // woof
When 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) // Jake
cat.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:
Date
objects are stringified and aren’t automatically converted back toDate
objectsundefined
properties are lostInfinity
is 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! :)