3

I am having difficulties with the sum function that calls the anonymous function code example from Eloquent Javascript (Chapter 6), while I understand what was clarified on this post, I really don't understand how the anonymous function is called.

From what I understand this code:

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}

function sum(numbers) {
  var total = 0;
  forEach(numbers, function (number) {
    total += number;
  });
  return total;
}
alert(sum([1, 10, 100, 1000]));

Is similar to this code (thanks to the assistance from @CKKiller in the other thread):

numbers = [1, 10, 100, 1000];
for (var i = 0; i < numbers.length; i++) {
  var number = numbers[i];

  function (number) {
    total += number;
  }
}
alert(total);

But I can't run the second code example, what is wrong with it? From my understanding it is not possible to call the syntax function (number) {}, but isn't that what the first example is instructing the function to do?

3 Answers 3

3

In the second code snippet, you're just declaring an anonymous function. Call it, and it should work fine. To "Immediately Invoke a Function Expression", you should do this:

(function (){
    // Your code
})();

Or

(function (){
    // Your code
}());

They're called IIFE's. (In quotes above)

As user1600680 pointed out in the comment below, to edit your code, you'll have to remove number from the parameter list. It would like like this:

(function () {
  total += number;
})();
Sign up to request clarification or add additional context in comments.

2 Comments

Or if you're feeling brave, you can do new function() { }
Should be pointed out that either the number parameter shown in the question will need to be removed since it shadows the number variable, or the number will need to be passed as an argument to the IIFE.
2

But I can't run the second code example, what is wrong with it?

You have a function declaration without a name:

function (number) {
    total += number;
}

Function declarations always have to include the name of the function. See section 13 in the specification.

From my understanding it is not possible to call the syntax function (number) {}, but isn't that what the first example is instructing the function to do?

Not it isn't. In the first example, you have a function expression because the function is defined in an expression context (it is passed as argument to an other function). Function expression don't need names. The expression is evaluated to a function object which is then passed as argument to forEach. function (number) {} does not call the function, it defines it.

I really don't understand how the anonymous function is called

There is nothing special about it. The important aspect is that functions are first-class objects, i.e. they can be assigned to variables and passed to other functions like any other value (primitive value or object). action refers to a function, so you can call that function with action(). The function is passed directly to forEach:

forEach(numbers, function (number) {
    // ...
});

Although it is called inside forEach, it can update the value of total since it was defined in sum and therefore is a closure which has access to all the local variables inside sum.

You could have also defined the function beforehand:

function sum(numbers) {
    var total = 0;
    function add(number) {
       total += number;
    }
    forEach(numbers, add);
    return total;
}

But if you use a value only once, then there is not need to assign it to a variable first (or declare a function for that matter). For example, you also passed the array directly to sum:

sum([1, 10, 100, 1000])

instead of assigning it to a variable first:

var numbers = [1, 10, 100, 1000];
sum(numbers);

An equivalent to the first code that shows similar behaviour would be:

var numbers = [1, 10, 100, 1000],
    total = 0,
    action = function(number) { // variable assignment -> expression context
        total += number;
    };

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

alert(total);

Comments

1

The 2nd example does NOT call the anonymous function, it only declares the function. Therefore, the for loop does nothing to the total variable (I assume it's declared previously somewhere). The alert(total) will only output what was last assigned to total (since the anonymous function never gets called, total doesn't get updated).

2 Comments

The 2nd example doesn't declare the function. It is invalid syntax and the alert will never happen.
Well at least it runs in rhino, replacing alert with print, and declaring total somewhere before the code with an initial value (and print does output this initial value)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.