Strange behavior of an array filled by Array.prototype.fill()

This is the same old problem with arrays (and objects in general) being references rather than values.

Specifically, when you do arr.fill([]), you are taking that one single empty array and using that to fill the parent one.

It's like saying:

var arr = new Array(5);
arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = [];

They all refer to the same array! So when you then go on to modify one of them, it looks like they're all modified (but really it's still the same one)

Unfortunately there's no simple way to assign an empty array to each one. You could do something like:

Array.apply(null, Array(5)).map(function() {return [];});

Essentially, create an (initialised) empty array of length 5 and map each (empty) value to a new [].

EDIT: Seems like I'm stuck in old times. As per @torazaburo's comment, you can use Array.from instead of Array.apply(null, Array(5)).map, like so:

Array.from( new Array(5), function() { return []; } );

The eleventh line of the ECMA doc of Array.prototype.fill is clearly giving the reason for the mystery.

Repeat, while k < final

Let Pk be ToString(k).

Let setStatus be Set(O, Pk, value, true).

ReturnIfAbrupt(setStatus).

Increase k by 1.

Here "value" is just a reference received. And they are setting it as a property to array directly. That means all the filled arrays are just reference to a single array object.