Объясните пример кода анонимной функции в 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
не обновляется).