Why do these two javascript 2d arrays behave differently?

In my function, I defined two arrays, the first (array1) has a pre-initialized length. I added a second array (array2) just for testing, because I thought the first one behaved strangely.

My code is:

function test(n = 3) { array1 = new Array(n).fill(new Array(n)); array2 = [ [undefined, undefined, undefined], [undefined, undefined, undefined], [undefined, undefined, undefined] ]; document.getElementById("output").innerHTML = JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><hr/>"; for (i = 0; i < n; i++) { array1[i][0] = i; array2[i][0] = i; } document.getElementById("output").innerHTML += JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><hr/>"; } 
 <button onclick="test();">Press to test</button> <br/><br/> <div id="output"></div> 

In a for loop, I'm trying to change the first value of the second dimensions. It should output [[0, undefined, undefined], [1, undefined, undefined], [2, undefined, undefined]] , as the second array does.

My questions are: why is this happening? And how can I make a pre-initialized array of length n in both dimensions that behaves like a second array?

+5
source share
2 answers

Because Array.fill

The fill() method fills all elements of the array from the beginning index to the ending index with a static value.

takes a static value and fills it with an array. Therefore, you get the same padding array in each element of array1 .

 function test(n = 3) { var array1 = new Array(n).fill(new Array(n)), array2 = [[undefined, undefined, undefined], [undefined, undefined, undefined], [undefined, undefined, undefined]], i; for (i = 0; i < n; i++) { array1[i][0] = i; array2[i][0] = i; } document.getElementById("output").innerHTML = array1 + " (array 1) <br/>" + array2 + " (array 2)<br/><br/><i>The commas with nothing in between mean undefined.</i>"; console.log(array1); console.log(array2); } 
 <button onclick="test();">Press to test</button><br/><br/> <div id="output"></div> 

To get an independent populated array, you can use Array.from and map the new array to the displayed values.

 var array = Array.from({ length: 3 }, _ => Array.from({ length: 3 }, _ => 4)); array[0][0] = 0; console.log(array); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 
+5
source

This is because, in the case of array1 it contains three arrays, but all three of them point to the same reference variable that was evaluated when new Array(n) was executed:

 var array1 = new Array(n).fill(new Array(n)); 

So, when the for loop works on array1 , it sets the value of the same array reference, while in the case of array2 these three arrays are different reference variables.

Here is a slightly modified version of your snippet. Pay attention to the entries in the console when the value of the element array1 . In the case of array1 all three child arrays change, and in the case of array2 , the array specified in the loop using the index i changes.

 function test(n = 3) { array1 = new Array(n).fill(new Array(n)); array2 = [ [undefined, undefined, undefined], [undefined, undefined, undefined], [undefined, undefined, undefined] ]; document.getElementById("output").innerHTML = JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><i>The commas with nothing in between mean undefined.</i><hr/>"; for (i = 0; i < n; i++) { array1[i][0] = i; array2[i][0] = i; console.log("Array 1: " + JSON.stringify(array1)); console.log("Array 2: " + JSON.stringify(array2)); } document.getElementById("output").innerHTML += JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><i>The commas with nothing in between mean undefined.</i><hr/>"; } 
 <button onclick="test();">Press to test</button> <br/><br/> <div id="output"></div> 
+6
source

Source: https://habr.com/ru/post/1271034/


All Articles