The Best Way to Deep Copy an Object in JavaScript

In this article, we’ll learn what shallow and deep copying is, and the best way to deep copy an object in JavaScript.

Shallow Copying vs Deep Copying

In a reassignment operation involving primitive data types such as strings, numbers and booleans, the original variable is copied by JavaScript. 

For example, consider the following code:

In this case, the value 3 is copied into y and then x is disconnected from y. So mutating y does not affect x.

Conversely, with non-primitive data types like arrays and objects, only a reference to the values is passed. So when the copy is mutated, the original also gets mutated. This is also known as shallow copying.

If we instead want to copy an object so that we can modify it without affecting the original object, we need to make a deep copy

5 Ways To Deep Copy Objects in JavaScript

In JavaScript, we can perform a copy on objects using the following methods:

Method Pros Cons
shallow copy with = clear and direct, the default

only shallow copies objects

JSON.stringify() and JSON.parse() deep copies nested objects

doesn’t copy functions

Object.assign() copies the immediate members of an object—including functions

doesn’t deep copy nested objects

the ... spread operator simple syntax, the preferred way to copy an object

doesn’t deep copy nested objects

Lodash cloneDeep() clones nested objects including functions

adds an external dependency to your project

These methods all have their pros and cons. Let’s take a closer look at each of them.

Shallow Copy an Object By Assignment

You can create a shallow copy of an object by simply assigning the original object to a new variable. 

Consider the following object:

To create a copy of the object user, we assign the object to a new variable like so:

As observed in the console output, we have now copied the object from user into clone.

However, all we did was create a reference to the original object. Whenever we mutate a property in the object clone, we’ll also end up mutating the original object (user) as we do in the following code:

So when a non-primitive data type (array or object) is assigned to a new variable, JavaScript makes a shallow copy of the original object.

Copy an Object with JSON.stringify() and JSON.parse()

The JSON.stringify() method takes in an object and creates a JSON string from it. The JSON.parse() method parses a string and returns a JavaScript object.

We can combine both of these methods to create a copy of an object in the following way:

When the copy object is mutated, the original object stays the same:

However, there is one caveat to using this approach: JSON.stringify() does not copy functions.

Suppose we have a method in our object user called incrementAge:

The function will not be available in the copied object.

Thus, this method achieves deep copy only if there is no function within the object.

Copy an Object with Object.assign()

Before ES6, Object.assign() was the most popular way to deep copy an object.

Object.assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn’t affect the original object.

However, one thing to remember about Object.assign() is that the method only performs a partial deep copy on objects.

To understand what that means, let’s consider the following:

As observed, we added the location property and passed an object as its value. Now we have a more complex structure that contains a nested object. 

Whenever we mutate a property within the nested object (in clone), it will also mutate the same property in the original object (users). Let’s take a look:

While the age property in the original object remained untouched, the city property was mutated by the reassignment operation.

Hence, the Object.assign() method should be used to deep copy objects that have no nested objects. 

The Best Way To Deep Copy in JavaScript: The Spread Operator

Another way to deep copy objects in JavaScript is with the ES6 spread operator. Using the three dots (...) collects all values on the original object into another object.

However, much like with Object.assign(), the spread operator only makes a partial copy. So any object with a nested object will not be deep copied.

To make a complete deep copy with the spread operator, we’ll have to write some additional code.

Consider the same user object but with a nested object:

To avoid mutating the original object which is user, we must spread the copy object before making direct changes to any of its properties. For any nested object, we must also spread that sub-object before making changes to any of its properties:

Here we mutated age which is a top-level property in clone, and city which is a sub-property.

This time the spread operation will give a complete deep copy wherein the original object will be unaffected by any mutation on the copy (clone)

Use Lodash cloneDeep() for Deep Copy

Lodash also provides a utility method _.cloneDeep() for deep cloning of objects in JavaScript.  Read more about the method here.

Conclusion

As you’ve seen, there are a number of ways to copy a variable in JavaScript. None of them is perfect for every occasion, so you’ll have to be careful to chose the best method for each situation.

To review, here are the methods and their pros and cons.

Method Pros Cons
shallow copy with = clear and direct, the default

only shallow copies objects

JSON.stringify() and JSON.parse() deep copies nested objects

doesn’t copy functions

Object.assign() copies the immediate members of an object—including functions

doesn’t deep copy nested objects

the ... spread operator simple syntax, the preferred way to copy an object

doesn’t deep copy nested objects

Lodash cloneDeep() clones nested objects including functions

adds an external dependency to your project


This content originally appeared on Envato Tuts+ Tutorials and was authored by Kingsley Ubah

In this article, we'll learn what shallow and deep copying is, and the best way to deep copy an object in JavaScript.

Shallow Copying vs Deep Copying

In a reassignment operation involving primitive data types such as strings, numbers and booleans, the original variable is copied by JavaScript. 

For example, consider the following code:

In this case, the value 3 is copied into y and then x is disconnected from y. So mutating y does not affect x.

Conversely, with non-primitive data types like arrays and objects, only a reference to the values is passed. So when the copy is mutated, the original also gets mutated. This is also known as shallow copying.

If we instead want to copy an object so that we can modify it without affecting the original object, we need to make a deep copy

5 Ways To Deep Copy Objects in JavaScript

In JavaScript, we can perform a copy on objects using the following methods:

Method Pros Cons
shallow copy with = clear and direct, the default

only shallow copies objects

JSON.stringify() and JSON.parse() deep copies nested objects

doesn't copy functions

Object.assign() copies the immediate members of an object—including functions

doesn't deep copy nested objects

the ... spread operator simple syntax, the preferred way to copy an object

doesn't deep copy nested objects

Lodash cloneDeep() clones nested objects including functions

adds an external dependency to your project

These methods all have their pros and cons. Let's take a closer look at each of them.

Shallow Copy an Object By Assignment

You can create a shallow copy of an object by simply assigning the original object to a new variable. 

Consider the following object:

To create a copy of the object user, we assign the object to a new variable like so:

As observed in the console output, we have now copied the object from user into clone.

However, all we did was create a reference to the original object. Whenever we mutate a property in the object clone, we'll also end up mutating the original object (user) as we do in the following code:

So when a non-primitive data type (array or object) is assigned to a new variable, JavaScript makes a shallow copy of the original object.

Copy an Object with JSON.stringify() and JSON.parse()

The JSON.stringify() method takes in an object and creates a JSON string from it. The JSON.parse() method parses a string and returns a JavaScript object.

We can combine both of these methods to create a copy of an object in the following way:

When the copy object is mutated, the original object stays the same:

However, there is one caveat to using this approach: JSON.stringify() does not copy functions.

Suppose we have a method in our object user called incrementAge:

The function will not be available in the copied object.

Thus, this method achieves deep copy only if there is no function within the object.

Copy an Object with Object.assign()

Before ES6, Object.assign() was the most popular way to deep copy an object.

Object.assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.

However, one thing to remember about Object.assign() is that the method only performs a partial deep copy on objects.

To understand what that means, let's consider the following:

As observed, we added the location property and passed an object as its value. Now we have a more complex structure that contains a nested object. 

Whenever we mutate a property within the nested object (in clone), it will also mutate the same property in the original object (users). Let's take a look:

While the age property in the original object remained untouched, the city property was mutated by the reassignment operation.

Hence, the Object.assign() method should be used to deep copy objects that have no nested objects. 

The Best Way To Deep Copy in JavaScript: The Spread Operator

Another way to deep copy objects in JavaScript is with the ES6 spread operator. Using the three dots (...) collects all values on the original object into another object.

However, much like with Object.assign(), the spread operator only makes a partial copy. So any object with a nested object will not be deep copied.

To make a complete deep copy with the spread operator, we'll have to write some additional code.

Consider the same user object but with a nested object:

To avoid mutating the original object which is user, we must spread the copy object before making direct changes to any of its properties. For any nested object, we must also spread that sub-object before making changes to any of its properties:

Here we mutated age which is a top-level property in clone, and city which is a sub-property.

This time the spread operation will give a complete deep copy wherein the original object will be unaffected by any mutation on the copy (clone)

Use Lodash cloneDeep() for Deep Copy

Lodash also provides a utility method _.cloneDeep() for deep cloning of objects in JavaScript.  Read more about the method here.

Conclusion

As you've seen, there are a number of ways to copy a variable in JavaScript. None of them is perfect for every occasion, so you'll have to be careful to chose the best method for each situation.

To review, here are the methods and their pros and cons.

Method Pros Cons
shallow copy with = clear and direct, the default

only shallow copies objects

JSON.stringify() and JSON.parse() deep copies nested objects

doesn't copy functions

Object.assign() copies the immediate members of an object—including functions

doesn't deep copy nested objects

the ... spread operator simple syntax, the preferred way to copy an object

doesn't deep copy nested objects

Lodash cloneDeep() clones nested objects including functions

adds an external dependency to your project


This content originally appeared on Envato Tuts+ Tutorials and was authored by Kingsley Ubah


Print Share Comment Cite Upload Translate Updates
APA

Kingsley Ubah | Sciencx (2022-01-11T12:25:06+00:00) The Best Way to Deep Copy an Object in JavaScript. Retrieved from https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/

MLA
" » The Best Way to Deep Copy an Object in JavaScript." Kingsley Ubah | Sciencx - Tuesday January 11, 2022, https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/
HARVARD
Kingsley Ubah | Sciencx Tuesday January 11, 2022 » The Best Way to Deep Copy an Object in JavaScript., viewed ,<https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/>
VANCOUVER
Kingsley Ubah | Sciencx - » The Best Way to Deep Copy an Object in JavaScript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/
CHICAGO
" » The Best Way to Deep Copy an Object in JavaScript." Kingsley Ubah | Sciencx - Accessed . https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/
IEEE
" » The Best Way to Deep Copy an Object in JavaScript." Kingsley Ubah | Sciencx [Online]. Available: https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/. [Accessed: ]
rf:citation
» The Best Way to Deep Copy an Object in JavaScript | Kingsley Ubah | Sciencx | https://www.scien.cx/2022/01/11/the-best-way-to-deep-copy-an-object-in-javascript/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.