loading...

Quick JavaScript tip #3: deep clone an array

oskarcodes profile image Oskar Codes Updated on ・3 min read

Quick JavaScript tips (3 Part Series)

1) Quick JavaScript tip #1: setInterval() with modifiable delay 2) Quick JavaScript tip #2: declare global variables from a function 3) Quick JavaScript tip #3: deep clone an array

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.

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 b, and not the value, which means that modifying b will instead update a because b is just a reference to a.

One way to solve this issue would be to unpack the original array in the new one, like so:

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: [[1,2],[3,4]]. Here's an example showing the problem:

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, a is also modified, because the inner arrays of b are still references to a. 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 parse and stringify:

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 val):

// 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 parse and stringify solution also works with JavaScript objects, so you could add the val method I used with arrays to the Object prototype in order to deep clone objects.

Quick JavaScript tips (3 Part Series)

1) Quick JavaScript tip #1: setInterval() with modifiable delay 2) Quick JavaScript tip #2: declare global variables from a function 3) Quick JavaScript tip #3: deep clone an array

Posted on by:

oskarcodes profile

Oskar Codes

@oskarcodes

I'm Oskar, a 15 years old amateur web and game developer. I like creating websites, and desktop apps using ElectronJS, and games using Unity and PICO-8!

Discussion

markdown guide