WreckingBall
WreckingBall

Reputation: 1328

Javascript Array Difference with Different Initialization Method

Can someone explain to me why the following happens in Javascript Console (Node 7.2.0):

Array in example I has different behavior than example II and III

EXAMPLE I

> var x = new Array(3).fill(new Array(2).fill(0))
> x
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> x[0][0] = 1;
> x
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ]

EXAMPLE II

> var y = [...new Array(3)].map(()=>{return [...new Array(2)].map(()=>0)})
> y
> [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> y[0][0] = 1
> [ [ 1, 0 ], [ 0, 0 ], [ 0, 0 ] ]

EXAMPLE III

> var y = []
> y.push([ 0, 0 ])
> y.push([ 0, 0 ])
> y.push([ 0, 0 ])
> y
> [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> y[0][0] = 1
> [ [ 1, 0 ], [ 0, 0 ], [ 0, 0 ] ]

It seems that different ways to initialize array will cause different behaviors of an array. I'm confused and thank you in advance.

Upvotes: 2

Views: 61

Answers (2)

RyanZim
RyanZim

Reputation: 6994

The reason for the difference is that in JS, objects (including arrays) are not copied, they are linked. In example I, you fill the array with a single array.

> var x = new Array(3).fill(new Array(2).fill(0))
// You have filled x with three links to the same array
> x
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> x[0][0] = 1;
// You have now modified the actual array, this change is reflected in all the links to it.
> x
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ]

What you are doing is the same as doing:

var a = [ 0, 0 ]
var x = [ a, a, a ]

OR

var a = [ 0, 0 ]
var x = []
x.push(a)
x.push(a)
x.push(a)

BTW, using new Array() is generally a bad practice. There is no benefit over the array literal syntax. Also, using new Array(n) makes "empty slots" in your array, which is very odd and can cause problems in your programs if you don't fill all the slots.

Upvotes: 0

mscdex
mscdex

Reputation: 106726

array.fill() returns the modified array, so you're filling an array with multiple references to the same array. That is why when you modify it in one place, it automatically shows up in the other places.

The first example is equivalent to doing something like:

var arr = [ 0, 0 ];
var x = [ arr, arr, arr ];

Upvotes: 7

Related Questions