Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

forEach on a 'new Array' isn't doing what I expect

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 can't seem to populate my output array. This is the goal:

range(1, 4) // [1, 2, 3, 4]

I'm getting this:

[undefined × 4]

Here is my code:

 function range(num1, num2) {
      var rangeArr = new Array((num2 + 1) - num1);
      return rangeArr.map(function(e, i, arr) {return arr[i] = num1 + i});
    }

What am I missing here? As far as I can tell the problem appears to have something to do with the way I'm utilizing 'new Array', but beyond that I'm lost.

Oh, and here's the part that really confuses me. This works fine:

function bleck() {
    var blah = [1, 2, 3, 4];
    var x = 'wtf';
    return blah.map(function(e, i, arr) {return arr[i] = x})
}

["wtf", "wtf", "wtf", "wtf"]

Thanks!!

like image 575
i_made_that Avatar asked Apr 24 '14 23:04

i_made_that


1 Answers

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).

like image 111
voithos Avatar answered Oct 27 '22 09:10

voithos