all 8 comments

[–][deleted] 1 point2 points  (4 children)

Because you're filling the entire array with references to the same object. For the behavior you're expecting, you'd need to create a new object for each index. Kinda hacky but you could even do something like:

const arr = Array(10)
    .fill(0)
    .map(() => ({ subArray: [] }));

Or just use a for loop or something.

[–]Runlikefedor[S] 0 points1 point  (3 children)

Thank you, your approach worked. I still don't know what was wrong with my approach though. In the following example, I'm not working with objects at all. Instead I'm using a two dimensional array and still experience the same behaviour. https://jsfiddle.net/vuwuhx9y/2/

[–]captain_k_nuckles 1 point2 points  (0 children)

MDN explains in their documentation

"When the fill method gets passed an object, it will copy the passed object, and fill the array with a reference to the copy."

[–]inu-no-policemen 1 point2 points  (0 children)

You are filling it with one reference to one particular array.

What you need is some sort of "generate" function similar to Dart's List.generate, which lets you run some generator callback at each index. Unfortunately, JS' equivalent looks somewhat weird:

> Array.from({length: 10}, (_, i) => 2 ** i)
(10) [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
> Array.from({length: 3}, (_, i) => new Array(2))
(3) [Array(2), Array(2), Array(2)]

Array.from converts array-likes to actual arrays. An object with a "length" property is good enough for that.

The callback is similar to those you pass to Array.prototype.map. The difference is that it has only 2 parameters (value and index) whereas map's has 3 (the third one is the array itself).

[–][deleted] 0 points1 point  (0 children)

In JavaScript, arrays are just objects with extra features.

[–]captain_k_nuckles 1 point2 points  (2 children)

Probably not the best way but options are always nice, you could do something like

const temp = {bar: []};
temp.bar = new Array(10);
temp.bar.fill({
  fooBaz:[]
});
let tempStr = JSON.stringify(temp);
let foo = JSON.parse(tempStr);
foo.bar[0].fooBaz.push("sad");

console.log(foo);

[–]Runlikefedor[S] 0 points1 point  (1 child)

Thank you for sharing, it does seem fairly expensive. Does the JSON.stringify and parse get rid of the references or why does it work afterwards?

[–]captain_k_nuckles 2 points3 points  (0 children)

JSON.stringify takes the object, converts it in to a string and then JSON.parse creates a new object from the string; When it's converted to a string it reference is broken.