I was working on a fun little thing on JS using nested arrays and was frustrated for nearly half an hour by this weird behavior. Here's some example code that gives the behavior:
var myArray = new Array(2);
myArray.fill([]);
out1.innerHTML = myArray;
myArray[0].push(0);
out2.innerHTML = myArray;
<div id="out1"></div>
<div id="out2"></div>
It's a bit tricky to see it how it's printed, but the push() is acting on every single nested array and not just myArray[0]. At first I thought it was something with push(), but I did some fiddling and found out that if I replaced myArray.fill([]);
with for(var i = 0; i < myArray.length; i++) { myArray[i] = []; }
that push() would then work fine, as in this example:
var myArray = new Array(2);
for(var i = 0; i < myArray.length; i++) { myArray[i] = []; }
out1.innerHTML = myArray;
myArray[0].push(0);
out2.innerHTML = myArray;
<div id="out1"></div>
<div id="out2"></div>
A few more details: it doesn't matter how big the parent array is, every nested array is pushed. It doesn't matter which nested array push() is called for, they'll all still be pushed. It doesn't matter what value is pushed into each nested array, it'll be pushed into them all.
Also, if I made a function to do the exact same thing as the for loop, the bug still happened. See snippet:
var myArray = new Array(2);
function fill(arr, filler) {
for(var i = 0; i < arr.length; i++) { arr[i] = filler; }
return arr;
}
myArray = fill(myArray, []);
out1.innerHTML = myArray;
myArray[0].push(0);
out2.innerHTML = myArray;
<div id="out1"></div>
<div id="out2"></div>
I haven't fiddled around to find out if it does this with more than one layer of nested arrays (so for example I don't know if it would do this to something like [ [ [], [] ], [ [], [] ] ]
).
As I said, I have a workaround for this using the for loop to fill the array instead of using myArray.fill(), but I'm wondering if anyone can explain the cause of this weird bug.