2

I'm using Array.fill to prepopulate an array with other arrays. Modifying the array of one indices also modifies the array of another. Meaning its the same object.

const arr = Array(2).fill([]);

arr[0].push('a');
arr[1].push('b');

// [['a', 'b'], ['a', 'b']]

I've been reading through some documentation but I don't see this behavior mentioned anywhere. Same thing happens with an object literal.

Does this make sense somehow?

Geuis
  • 41,122
  • 56
  • 157
  • 219
  • This does not answer your question, but if you're insteresting in solve this unexpected behaviour you can use Array.from({length : 2}, ()=>[]); to prefill the Array. https://jsfiddle.net/qf8z69ma/ – Jose Hermosilla Rodrigo Jun 13 '16 at 21:31
  • @JoseHermosillaRodrigo yep that was the same answer I ended up coming to. – Geuis Jun 14 '16 at 18:19

2 Answers2

3

Yes it does.

You are passing a reference to an created object instance. If you would first declare the array (eg. var c = []) and then populate arr with it you would get the same behavior.

const c = [];
const arr = Array(2).fill(c);

c.push("a");    
c.push("b");

// c ["a", "b"]
// arr [reference to c, reference to c] => [["a","b"], ["a", "b"]]
veritas
  • 2,034
  • 1
  • 16
  • 30
  • 1
    Cool thanks for verifying. I figured thats what was happening but wasn't sure if that was the right behavior. – Geuis Jun 13 '16 at 21:30
1

Yes, it does make sense.

fill expects a value that is put in all the indices, not a function that produces a new value for every index. And it doesn't implicitly clone the value you passed either (no standard function does that). This is just the usual assignment behaviour, wherein objects (reference values) stay the same.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375