1

I can't figure out how this works. Here's the code.

function forEach(array, action) {
  for (var i = 0; i < array.length; i++) 
    action (array[i]);  
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
forEach(numbers, function(number) {
  sum += number;
});
console.log(sum);

I get that sum =+ number; is getting passed to forEach and looping through the array numbers. But I can't make out the details of how that happens. Putting function(number) {sum =+ number} in place of action like so

for (var i = 0; i < [1, 2, 3, 4, 5].length; i++)
  function(number) {
    sum += number;
  } (array[i]);
}

doesn't make sense, nor does it run. What would work is

var numbers = [1, 2, 3, 4, 5], sum = 0;
for (var i = 0; i < numbers.length; i++)
  sum += (numbers[i]);
debug(sum);
console.log(sum);

which is as much as I can compress it and make it work. But how do you get to here? In other words what's really happening?

Thanks for any help. This concept seems basic to Haverbeke's approach, so I think I'd better understand it.

Greg
  • 2,359
  • 5
  • 22
  • 35
  • 2
    Your second version does not work because it has a syntax error. If you put `(...)` around the function definition, it works. So, seems like you understood what's happening, the thing that tripped you off was function *declaration* vs function *expression*. – Felix Kling Aug 28 '15 at 15:01
  • 1
    @Andreas: You know what I mean :P (fixed) – Felix Kling Aug 28 '15 at 15:06
  • I agree with @Felix - you can't pass a value in to a function declaration, but you can pass a value into the value defined by the definition (i.e. the function itself). Putting brackets around the function allows you to treat it as an expression rather than a declaration – Sam Aug 28 '15 at 15:10

2 Answers2

2

The forEach function is calling action for each element in the array.

All forEach is doing here is abstracting away a loop like the one you pretty much had:

for (var i = 0; i < numbers.length; i++){
    sum += numbers[i];
}

Maybe the action (array[i]) tripped you up. Understand that this is invoking action with the element in the array, so more intuitively it would look like action(array[i]).

For foreach, this invocation is taken care of inside of the code -- at the action (array[i]). That's why you can just pass a function without calling it yourself.

In a sentence, forEach works by calling a function your provide on each element in an array you provide.

If you need another example to clear this up, consider this (Assume that forEach is the one in your question):

var greetings = ["Hello", "Hi", "How are ya"];

function printGreeting(greeting){
    console.log(greeting, "Greg");
}

forEach(greetings, printGreeting);

As you can see here, printGreeting is getting called on all of the elements in greetings by being passed each value of greetings[i].

Anything you would do with a for loop over an array can be done perhaps more easily using the forEach loop.

For more info, check out the standard Array.prototype.forEach() here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

  • 1
    Your first few lines got me to see what's going on. Now if I can hold the thought and make mine, i.e., remember and understand it. – Greg Aug 28 '15 at 16:21
  • 1
    If you're happy with the answer, could you click the check button to accept it? That'll show that you're not still seeking answers. (I also want to see what'll happen) :) – Jabari King Aug 28 '15 at 17:05
0

A proper translation, as what @FelixKling said suggests (even if he didn't), works fine:

var array = numbers;
var action = function(number) {
    sum += number;
}
for (var i = 0; i < array.length; i++) {
    action(array[i]);
}
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • Mmh no, that doesn't work and is not what I suggested :P (but yeah, I missed the `array` part). It has to be `(function() { ... }(...));`. – Felix Kling Aug 28 '15 at 15:06
  • I think you mean `(function() { ... })(...);`, felix. – Sam Aug 28 '15 at 15:13
  • @FelixKling Thanks for your replies. Not sure where to put the parentheses. I tried various configurations. None worked, but maybe I'm not getting exactly what you're driving at. – Greg Aug 28 '15 at 17:10