Quick JavaScript tip #3: deep clone an array
Tags: javascript, tip, array
Published: 2020-03-05 18:02:05

When programming in JavaScript, you might face a situation where you have to clone an array, which means you want to create a second variable containing the same array as the original one. At first glance, this might seem like a simple problem; just assign the original array to a new variable. But JavaScript doesn't work like that with arrays. Let's see why with an example.
```javascript
var a = [1,2,3]; // create the original array
var b = a; // store it in another variable "b"

b[1] = 4; // assign 4 to the second element of the array "b"

// now let's see the output...
console.log(b); // results in [1,4,3]
console.log(a); // also results in [1,4,3]
```

This behavior is due to JavaScript actually giving a reference to <code>b</code>, and not the value, which means that modifying <code>b</code> will instead update <code>a</code> because <code>b</code> is just a reference to <code>a</code>.

One way to solve this issue would be to unpack the original array in the new one, like so:
```javascript
var a = [1,2,3]; // create the original array
var b = [...a]; // unpack "a" to "b"

b[1] = 4; // assign 4 to the second element of the array "b"

// now let's see the output...
console.log(b); // results in [1,4,3]
console.log(a); // results in [1,2,3]
```

Yay! This works! But there is an issue with this, as unpacking still keeps references in lower level arrays, which means that this solution wouldn't work with an array like this one: <code>[[1,2],[3,4]]</code>. Here's an example showing the problem:
```javascript
var a = [[1,2],[3,4]]; // create the original array
var b = [...a]; // unpack "a" to "b"

b[0].push(3); // add 3 to the first element of the array "b"

// now let's see the output...
console.log(b); // results in [[1,2,3],[3,4]]
console.log(a); // also results in [[1,2,3],[3,4]]
```
As you can see, <code>a</code> is also modified, because the inner arrays of <code>b</code> are still references to <code>a</code>. What we want is to **deep** clone the original array, and not keep references to the previous one.
However, if you know that the array you are cloning is only one dimensional, you are totally free to use this method, as it is quite simple and easy to read.

Now the solution to deep clone arrays that I prefer, and that is most commonly used in my experience, is to use JSON <code>parse</code> and <code>stringify</code>:
```javascript
var a = [[1,2],[3,4]]; // create the original array
var b = JSON.parse(JSON.stringify(a)); // stringify and then parse "a"

b[0].push(3); // add 3 to the first element of the array "b"

// now let's see the output...
console.log(b); // results in [[1,2,3],[3,4]]
console.log(a); // results in [[1,2],[3,4]]
```

And there you go! You now know how to deep clone arrays in JavaScript.
However, this solution isn't very beautiful to read, so an option is to add a new deep cloning method to the Array prototype (I'll call it <code>val</code>):
```javascript
// define the method
Array.prototype.val = function() {
  return JSON.parse(JSON.stringify(this));
}

// and use it like so
var a = [[1,2],[3,4]];
var b = a.val(); // successfully deep clones the original array
```

Please note that the JSON <code>parse</code> and <code>stringify</code> solution also works with JavaScript objects, so you could add the <code>val</code> method I used with arrays to the Object prototype in order to deep clone objects.