0

Why does invoking Array.prototype.map directly on Array instance o result in an "unmodified" array?

var o = Array(3); // [ undefined, undefined, undefined ]
o.map((x,y) => y*2); //  [ undefined, undefined, undefined ]

Instead, I have to use apply (or call):

Array.apply(0, o).map((x, y) => y*2)); // [ 0, 2, 4 ]

What am I missing?

Finally, an alternative to the above is:

[...o].map((x, y) => y*2); // [ 0, 2, 4]

I presume because this corrects whatever is missing in my original implementation.

Ben Aston
  • 53,718
  • 65
  • 205
  • 331

1 Answers1

4

Why does invoking Array.prototype.map directly on Array instance o result in an "unmodified" array?

Because .map only works on elements that actually exist. Array(3) creates an empty array of length 3. Put differently: .map omites holes.

Instead, I have to use apply (or call): ... What am I missing?

Array.apply(0, o) is equivalent to Array(undefined, undefined, undefined) in your case, i.e. you are creating an array that contains three elements.

The different becomes more apparent if you compare

console.dir(Array(3));
// vs
console.dir(Array.apply(null, Array(3)));

The first one only has property length, the second one also has properties 0, 1 and 2.

Finally, an alternative to the above is: ...

The spread operator will call o[Symbol.iterator]. The iterator of an array will iterate over holes, just like you would when using a normal for loop.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143