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 leto constpiuttosto 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 .