No caso da expressão de função anônima, a função é anônima - literalmente, não tem nome. A variável à qual você está atribuindo tem um nome, mas a função não. (Atualização: isso era verdade através do ES5. A partir do ES2015 [também conhecido como ES6], muitas vezes uma função criada com uma expressão anônima obtém um nome verdadeiro [mas não um identificador automático], continue lendo ...)
Os nomes são úteis. Os nomes podem ser vistos em rastreamentos de pilha, pilhas de chamadas, listas de pontos de interrupção, etc. Os nomes são uma coisa boa ™.
(Você costumava ter que tomar cuidado com as expressões de função nomeada em versões mais antigas do IE [IE8 e abaixo], porque eles criaram por engano dois objetos de função completamente separados em dois momentos completamente diferentes [mais no meu artigo do blog Double take ]. Se você precisar suporte IE8 [!!], provavelmente é melhor ficar com expressões de função anônimas ou declarações de função , mas evite expressões de função nomeadas.)
Uma coisa importante sobre uma expressão de função nomeada é que ela cria um identificador dentro do escopo com esse nome para a função dentro do corpo da função:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
No entanto, a partir do ES2015, muitas expressões de função "anônimas" criaram funções com nomes, e isso foi precedido por vários mecanismos JavaScript modernos que eram bastante inteligentes ao inferir nomes a partir do contexto. No ES2015, sua expressão de função anônima resulta em uma função com o nome boo
. No entanto, mesmo com a semântica ES2015 +, o identificador automático não é criado:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
A atribuição do nome da função é feita com a operação abstrata SetFunctionName usada em várias operações na especificação.
A versão curta é basicamente qualquer momento em que uma expressão de função anônima aparece no lado direito de algo como uma atribuição ou inicialização, como:
var boo = function() { /*...*/ };
(ou pode ser let
ou em const
vez de var
) , ou
var obj = {
boo: function() { /*...*/ }
};
ou
doSomething({
boo: function() { /*...*/ }
});
(esses dois últimos são realmente a mesma coisa) , a função resultante terá um nome ( boo
, nos exemplos).
Há uma exceção importante e intencional: atribuir a uma propriedade em um objeto existente:
obj.boo = function() { /*...*/ }; // <== Does not get a name
Isso ocorreu devido a preocupações com vazamento de informações quando o novo recurso estava passando pelo processo de adição; detalhes em minha resposta a outra pergunta aqui .