Deep Cloning Objects and Arrays in Javascript
By: Kevin Mora Gamboa
Tags: Technology, Programming, JavaScript, Arrays, Cloning

There are times when we need to create a copy of the data inside a variable so that we can manipulate it without the risk of changing the original data referenced.

Now, more often than not, when you initiate the copy of a variable into another one, you expect that if you modify the new one, the original will keep the same value. In Javascript, this is easy if we are working with primitive values, but if we want to copy Arrays or Objects, reaching our goal becomes a little bit trickier.

In JavaScript, there are two ways to copy a variable value:

Shallow clone

Deep clone

Before we define what a Shallow Clone and Deep Clone are, I’m going to talk about copying primitive data types.

When we are working with primitive values, we don’t need to worry about shallow or deep cloning when copying variables, because when you create a copy of them, there will always be a brand new copy of its value on the receiver’s end.

Primitive data types are the building blocks of many programming languages and in JavaScript, they are defined by:

Boolean

String

Number

Undefined

Null

Symbol (this one is new in ES6)

Let’s see an example:

As you can see above, when we copy a primitive value and then we update the new variable, the original reference doesn’t get affected by the change.

So now that we have proven that primitive values don’t modify the original one, we need to define what is a Shallow or a Deep Clone when we try to copy an Object or an Array.

What is Shallow Cloning?

When we do a Shallow Clone, a new Array or Object is not created, instead a copy of the references is created i.e., only the memory addresses are copied. So if we were to make changes to the entries or members of the new copy, then effectively we will be making changes to the data referenced by the original one, as both variables will be pointing to the same memory space.

What is Deep Cloning?

A Deep Clone means actually creating a brand new Array or Object and iteratively copying over the values into new structures; this way, changes to it will never affect the original one and vice-versa.

Let’s take a look at how this works, say we have a simple array with Primitive Values inside, for example:

const simpleArray = [1,2,3];

If we copy this array to another variable and then we modify the new one, we can see that both arrays were affected.

In the example above we made a Shallow Clone. This could be a problem sometimes if we expect the original variable will not be affected by changes into the new copy. It is very common to get a problem like this one and we can spend a lot of time debugging until we realize that we are actually doing a Shallow Clone.

Now, we can get the same error with an Object, for example:

It is important to say that when we copy Arrays and/or Objects, we are copying them by reference instead of by value.

So, how can I avoid this? Well, it’s pretty easy! We can use the spread operator (ES5+).

The Spread Operator on arrays works as

The Spread Operator on Objects work as

Also, for Object’s data we can use Object.assign, for example:

So, what about nested Objects and Arrays?

The nested objects inside of that object or array will still be a reference/pointer to the original, so if we make a copy and then we update the new one, it will update the original as well. For example:

So, what can we do if we have nested Arrays and Objects?

We can use our secret weapon JSON.parse() and JSON.stringify(). First, we turn an object into a string and then we parse it to an object again, doing it this way ensures that we can create a complete new nested array and/or object.

We just did our deep clone successfully 🎉.

I hope this helps you, saves you lots of hours of debugging and testing, and it made for an insightful reading 😉