6

Is array.slice enough to clone a multidimensional Array in JavaScript?

For example:

 var array = [
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]
    ];

 var b = array.slice();
 console.log(b);

I saw a secondary implementation as this from Play by Play: Lea Verou on pluralsight:

 b =  array.slice().map( function(row){ return row.slice(); });
icedwater
  • 4,701
  • 3
  • 35
  • 50
runners3431
  • 1,425
  • 1
  • 13
  • 30

2 Answers2

5

The docs are pretty clear:

The slice() method returns a shallow copy of a portion of an array into a new array object.

So the answer is no: slice by itself is not enough to clone a multidimensional array. It will only clone one dimension. You need to recursively clone each element (the way the "secondary implementation" you posted is doing) if you want a deep clone.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 1
    when i did console.log(b) on both implementations, it seemed to return the same output. that's why i was confused. – runners3431 Aug 25 '14 at 19:14
  • @runners3431 - Using console logging to test whether one object is a clone of another is dubious; after all, if they're clones, they _should_ produce the same output. Much better would be to log the result of an identity test (e.g., `console.log(array[0] === b[0]);`). Incidentally, in the "secondary implementation", `b = array.slice().map(...)` can be replaced by `b = array.map(...)`; the `map()` function is returning a new array anyway, so making a shallow copy of `array` doesn't buy anything. – Ted Hopp Aug 25 '14 at 20:33
  • if one is a shallow clone copy, than wouldn't that not include some parts of the array? – runners3431 Aug 27 '14 at 17:18
  • @runners3431 - Sorry, I don't understand your last comment. Can you rephrase and/or elaborate? A shallow clone copy will contain all the same elements (identically--not clones/copies) as the original array, just in a new array object. – Ted Hopp Aug 27 '14 at 17:45
5

From MDN:

The slice() method returns a shallow copy of a portion of an array into a new array object.

That is, it will not clone the internal arrays / objects. Observe:

 var array = [
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]
    ];

 var b = array.slice();
 b[0].push(10); 
 console.log(array);
 > [ [1, 2, 3, 10], [4, 5, 6], [7, 8, 9] ]

So if you want a deep copy of your 2D array, then you'd have to go with the map method (or something similar).

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331