1

Could someone explain me why this statement generates a new array of null values instead a array of 1's?

let a = [...Array(3).map(_ => 1)];
console.log(a);

results [null, null, null] instead of [1,1,1]

But, the following code...

let b = [...Array(3)].map(_ => 1)
console.log(b);

results [1,1,1]

danh
  • 62,181
  • 10
  • 95
  • 136
sikmowe
  • 33
  • 6

2 Answers2

2

Some might consider this a dup of the post I referred to in the comments. The gist is that the array constructor creates an array of undefined references, and the spread operator creates an array of references to undefined.

map skips undefined references, but maps happily over refs to undefined. See it with a console.log() side effect.

new Array(3).map(el => console.log('this code is never reached'))

Compared this to

[...new Array(3)].map(el => console.log(el))
danh
  • 62,181
  • 10
  • 95
  • 136
1

When you creating empty array that have a length, all slots are unassigned, they don't even have undefined value. Map on the other hand, can only iterate thru assigned values.

Good explanation is on developer.mozilla.org

MDN Array()->Parameters->arrayLength

(...) Note: this implies an array of arrayLength empty slots, not slots with actual undefined values (...)

MDN map()->description

(...) callback is invoked only for indexes of the array which have assigned values (...)

This is why on Array(3).map(_=>1), map() callback have no effect.

Second part is how spread is working. When you are spreading array with 3 empty slots, you are creating new array, that have filled slots. Now you have all slots with value undefined. From now, map will work as expected.

Examples:

Welcome to Node.js v12.20.1.
Type ".help" for more information.
> Array(3)
[ <3 empty items> ]

> [...Array(3)]
[ undefined, undefined, undefined ]

> const a = []
> a.length = 2
> a
[ <2 empty items> ]

> [...a]
[ undefined, undefined ]
undg
  • 787
  • 4
  • 14