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