В случае выражения анонимной функции функция анонимна - буквально, у нее нет имени. Переменная, которой вы ее назначаете, имеет имя, а функция - нет. (Обновление: это было правдой через ES5. Начиная с ES2015 [также известного как ES6], часто функция, созданная с помощью анонимного выражения, получает настоящее имя [но не автоматический идентификатор], читайте дальше ...)
Имена полезны. Имена можно увидеть в трассировке стека, стеках вызовов, списках точек останова и т. Д. Имена - это хорошая вещь ™.
(Раньше вам приходилось остерегаться именованных функциональных выражений в более старых версиях IE [IE8 и ниже], потому что они по ошибке создавали два полностью отдельных функциональных объекта в два совершенно разных момента [подробнее в моей статье блога Двойной дубль ]. Если вам нужно поддерживают IE8 [!!], вероятно, лучше придерживаться анонимных функциональных выражений или объявлений функций , но избегайте именованных функциональных выражений.)
Одним из ключевых моментов в выражении именованной функции является то, что оно создает идентификатор в области видимости с этим именем для функции в теле функции:
var x = function example() {
console.log(typeof example);
};
x();
console.log(typeof example);
Однако, начиная с ES2015, многие «анонимные» функциональные выражения создают функции с именами, и этому предшествовали различные современные движки JavaScript, которые довольно умно выводили имена из контекста. В ES2015 ваше анонимное выражение функции приводит к функции с именем boo
. Однако даже с семантикой ES2015 + автоматический идентификатор не создается:
var obj = {
x: function() {
console.log(typeof x);
console.log(obj.x.name);
},
y: function y() {
console.log(typeof y);
console.log(obj.y.name);
}
};
obj.x();
obj.y();
Назначение имени функции выполняется с помощью SetFunctionName абстрактной операции используемой в различных операциях в спецификации.
Краткая версия - это в основном каждый раз, когда выражение анонимной функции появляется справа от чего-то вроде присваивания или инициализации, например:
var boo = function() { };
(или это могло быть let
или const
скорее чем var
) , или
var obj = {
boo: function() { }
};
или
doSomething({
boo: function() { }
});
(последние два на самом деле одно и то же) , получившаяся функция будет иметь имя ( boo
в примерах).
Есть важное и преднамеренное исключение: присвоение свойству существующего объекта:
obj.boo = function() { };
Это произошло из-за опасений по поводу утечки информации, возникших, когда новая функция находилась в процессе добавления; подробности в моем ответе на другой вопрос здесь .