I\'m just learning how to use JS higher-order functions (map, forEach, reduce, etc), and have stumbled into confusion. I\'m trying to write a simple \'range\' function, but
The problem is that map
doesn't iterate undefined entries (*).
I suggest using a for
loop instead:
var rangeArr = new Array((num2 + 1) - num1);
for(var i=0; i<=num2-num1; ++i)
rangeArr[i] = num1 + i;
return rangeArr;
(*) With undefined entries I mean rangeArr.hasOwnProperty(i) === false
, not to be confused with rangeArr[i] === void 0
.
The forEach
method iterates over the indices of the array. Interestingly enough, when you create a new array via new Array(n)
, it contains no indices at all. Instead, it just sets its .length
property.
> var a = new Array(3);
> console.info(a)
[]
> console.info([undefined, undefined, undefined])
[undefined, undefined, undefined]
MDN describes forEach
, and specifically states:
forEach executes the provided callback once for each element of the array with an assigned value. It is not invoked for indexes which have been deleted or elided.
Here's a neat technique to get an array with empty, but existing, indices.
var a = Array.apply(null, Array(3));
This works because .apply
"expands" the elided elements into proper arguments, and the results ends up being something like Array(undefined, undefined, undefined)
.
The array is defined with 4 entires each of which is undefined.
Map will not iterate over undefined entires, it skips them.
callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes that are undefined, those which have been deleted or which have never been assigned values.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
When you create a new Array(x)
it is creating what is called a sparse array, which might behave a bit differently, as you can see, some browsers will say [undefined x 20,"foo", undefined x 5]
if you just set one value, and I believe it doesn't iterate over those values.