1

I'm creating a 3x3 grid in JavaScript with all values initialized to false like so:

let myGrid = Array(3).fill(Array(3).fill(false));

After initialization the grid values are:

[false, false, false],
[false, false, false],
[false, false, false]

If I then set the element [0,0] to true, like:

myGrid[0][0] = true;

I would expect the values to be:

[true,  false, false],
[false, false, false],
[false, false, false]

But in fact, the resulting 2d array becomes:

[true, false, false],
[true, false, false],
[true, false, false]

Why has the first element in every inner array changed when I've only set the first element of the first array?

jbyrd
  • 5,287
  • 7
  • 52
  • 86
  • You should also check compatibility for things like this. Mozilla says this isn't available in Opera or IE. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill?v=example – DanielC May 01 '17 at 21:41

2 Answers2

2

fill(), when passed an array, fills references to that array. Thus, your second-dimensional arrays are actually the same array. Whatever you do to one is done to its reference, which naturally gets reflected in all others pointing to that reference.

To illustrate this, what you did in your question is the same thing as doing:

var $a = [false, false, false];
let myGrid = array(3);
myGrid[0] = $a;
myGrid[1] = $a;
myGrid[2] = $a;

Every time you change the value of say myGrid[0], you're actually accessing the reference to $a, and since that reference is still what myGrid[1] and myGrid[2] point to, you'll actually be modifying them as well.

To avoid this, you'd have to define a new array each time you want to assign a value to the myGrid array.

Cedric Ipkiss
  • 5,662
  • 2
  • 43
  • 72
0

That's because your grid is an array of 3 times the same array.

Maybe it's more clear if you see your initialization code broken in 2 lines:

let line = Array(3).fill(false); // [false, false, false], alright
let myGrid = Array(3).fill(line); // wrong: you fill the array with 3 times the same object (the array created at line above)

Edit: a more correct way to initialize the array (not sure it's the best):

let myGrid = Array(3).fill(0).map(x => [false, false, false])
Hugues M.
  • 19,846
  • 6
  • 37
  • 65