Объясните пример кода анонимной функции в Eloquent Javascript, глава 6

У меня возникли трудности с функцией суммы, которая вызывает пример кода анонимной функции из Eloquent Javascript (глава 6), хотя я понимаю, что было разъяснено в этом посте, я действительно не понимаю, как вызывается анонимная функция.

Из того, что я понимаю этот код:

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

Аналогичен этому коду (благодаря помощи @CKKiller в другом потоке):

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

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

Но я не могу запустить второй пример кода, что с ним не так? Насколько я понимаю, невозможно вызвать синтаксическую функцию (число) {}, но разве это не первый пример, который инструктирует функцию?

3 ответа

Во втором фрагменте кода вы просто объявляете анонимную функцию. Назовите это, и это должно работать хорошо. Чтобы "немедленно вызвать выражение функции", вы должны сделать это:

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

Или же

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

Их называют IIFE. (В цитатах выше)

Как указал пользователь 1600680 в комментарии ниже, для редактирования кода вам придется удалить number из списка параметров. Было бы так:

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

Но я не могу запустить второй пример кода, что с ним не так?

У вас есть объявление функции без имени:

function (number) {
    total += number;
}

Объявления функций всегда должны включать имя функции. Смотрите раздел 13 в спецификации.

Из моего понимания невозможно назвать синтаксис function (number) {}, но разве это не то, что первый пример инструктирует функции делать?

Не это не так. В первом примере у вас есть выражение функции, потому что функция определена в контексте выражения (она передается в качестве аргумента другой функции). Выражению функции не нужны имена. Выражение вычисляется для объекта функции, который затем передается в качестве аргумента forEach, function (number) {} не вызывает функцию, она определяет ее.

Я действительно не понимаю, как называется анонимная функция

В этом нет ничего особенного. Важным аспектом является то, что функции являются первоклассными объектами, то есть они могут быть назначены переменным и переданы другим функциям, как любое другое значение (примитивное значение или объект).action относится к функции, так что вы можете вызвать эту функцию с action(), Функция передается напрямую forEach:

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

Хотя это называется внутри forEach, он может обновить значение total так как это было определено в sum и, следовательно, является замыканием, которое имеет доступ ко всем локальным переменным внутри sum,

Вы могли бы также определить функцию заранее:

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

Но если вы используете значение только один раз, то нет необходимости сначала назначать его переменной (или объявлять функцию в этом отношении). Например, вы также передали массив напрямую sum:

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

вместо того, чтобы сначала присвоить его переменной:

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

Эквивалентом первого кода, который показывает подобное поведение, будет:

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

Второй пример НЕ вызывает анонимную функцию, он только объявляет функцию. Поэтому цикл for ничего не делает с total переменная (я предполагаю, что она где-то объявлена ​​ранее). alert(total) будет выводить только то, что было в последний раз присвоено итоговому значению (поскольку анонимная функция никогда не вызывается, total не обновляется).

Другие вопросы по тегам