Undefined values in Array(len) initializer
The array constructor creates an array with the given length. It does not create the keys. Array.prototype.map
's callback function is only executed for the elements in the list.
That is, all values which are associated with a key (integer) 0 ≤ i < length.
Array(3)
has zero keys, so.map
's callback is never triggered.[void 0, void 0, void 0]
has three keys, for which the callback function is executed.Array(3).hasOwnProperty(0); // false [void 0, void 0, void 0].hasOwnProperty(0); // true
The specification and its polyfill are mentioned at MDN. At line 47, if (k in O) {
shows that non-existant keys are not treated by the callback function.
From MDN:
callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
For the array a
, you've instantiated an array of length 3 but have not assigned any values. The map function finds no elements with assigned values, so it does not produce a new array.
For the array b
, you've instantiated an array of 3 elements, each with the value undefined
. The map function finds 3 elements with assigned values, and returns '0' as the new value for each of them in a new array.
map
only iterates existing properties, not empty indices.
Therefore, if you want it to work, you must first fill the array.
There are multiple ways to do that, for example:
.fill()
, introduced in ES6console.log(new Array(3).fill().map(function(){ return 0; }));
Call
concat
withapply
:var arr = [].concat.apply([], new Array(3)); console.log(arr.map(function(){ return 0; }));
An old
for
loop.var arr = new Array(3); for(var i=0; i<arr.length; ++i) arr[i] = 1; /* whatever */ console.log(arr.map(function(){ return 0; }));
Use some idea from Most efficient way to create a zero filled JavaScript array?
Etcetera.