Nel caso dell'espressione di funzione anonima, la funzione è anonima - letteralmente, non ha nome. La variabile a cui la stai assegnando ha un nome, ma la funzione no. (Aggiornamento: questo era vero attraverso ES5. A partire da ES2015 [aka ES6], spesso una funzione creata con un'espressione anonima ottiene un vero nome [ma non un identificatore automatico], continua a leggere ...)
I nomi sono utili. I nomi possono essere visualizzati nelle tracce dello stack, negli stack delle chiamate, negli elenchi di punti di interruzione, ecc. I nomi sono una buona cosa ™.
(Dovevi fare attenzione alle espressioni di funzione con nome nelle versioni precedenti di IE [IE8 e inferiori], perché creavano per errore due oggetti funzione completamente separati in due momenti completamente diversi [più nel mio articolo del blog Double take ]. Se necessario supporta IE8 [!!], probabilmente è meglio attenersi a espressioni di funzioni anonime o dichiarazioni di funzioni , ma evitare espressioni di funzioni con nome.)
Una cosa fondamentale di un'espressione di funzione denominata è che crea un identificatore nell'ambito con quel nome per la funzione all'interno del corpo della funzione:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
A partire da ES2015, tuttavia, molte espressioni di funzioni "anonime" creano funzioni con nomi, e questo è stato preceduto da vari motori JavaScript moderni che erano piuttosto intelligenti nell'inferenza di nomi dal contesto. In ES2015, l'espressione della funzione anonima risulta in una funzione con il nome boo
. Tuttavia, anche con la semantica ES2015 +, l'identificatore automatico non viene creato:
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();
L'assegnazione del nome della funzione viene eseguita con l' operazione astratta SetFunctionName utilizzata in varie operazioni nelle specifiche.
La versione breve è fondamentalmente ogni volta che un'espressione di funzione anonima appare sul lato destro di qualcosa come un assegnamento o un'inizializzazione, come:
var boo = function() { /*...*/ };
(o potrebbe essere let
o const
piuttosto che var
) , o
var obj = {
boo: function() { /*...*/ }
};
o
doSomething({
boo: function() { /*...*/ }
});
(questi ultimi due sono davvero la stessa cosa) , la funzione risultante avrà un nome ( boo
, negli esempi).
C'è un'eccezione importante e intenzionale: l'assegnazione a una proprietà su un oggetto esistente:
obj.boo = function() { /*...*/ }; // <== Does not get a name
Ciò era dovuto alle preoccupazioni sulla fuga di informazioni sollevate durante il processo di aggiunta della nuova funzionalità; dettagli nella mia risposta a un'altra domanda qui .