Help understanding this behaviour in arrays

Please consider the following code below:

let original = [[0], [1], [2], [3]];
let copy = [...original];
copy.push("X");//mutating the FIRST dimension of "copy"
console.log(original);//[ [ 0 ], [ 1 ], [ 2 ], [ 3 ] ] //nothing changes
copy[0].push("X");//mutating the SECOND dimension of "copy"
console.log(original);//[ [ 0, 'X' ], [ 1 ], [ 2 ], [ 3 ] ]
                            //  ^ mutates the original also

I don’t understand why this behavior occurs, can someone please explain why it occurs and how to override it?

It looks like using the spread operator in your assignment to copy is making a reference to original and creating a copy. So when you change copy, you also change the original.

What happens if you create copy by pushing the contents of original into a new array?

That’s because spread creates a shallow copy of the array, i.e. it copies only one level deep. The original array contains references to other arrays so the references (and not values) are copied.

P.S. push adds to the end of an array.

So is there a way of copying all dimensions, or i’ll have to make a function to do that stuff?

@Marmiz I mentioned you in case you can suggest a way of doing that, sorry for the inconvenience, thanks in advance!

Yep, a recursion :slight_smile:
You can simply create a small utility function that “deep” copy the whole tree, instead of limiting to the references.

For a case like this you should be able to do it yourself.
For production like cases, you can have a look for example on how lodash implements deep clone

1 Like

Apart from methods mentioned by @Marmiz, there is a quick-and-dirty way to create a deep copy:

JSON.parse(JSON.stringify(arrayToClone))
1 Like