Im Fall des anonymen Funktionsausdrucks ist die Funktion anonym - buchstäblich hat sie keinen Namen. Die Variable, der Sie sie zuweisen, hat einen Namen, die Funktion jedoch nicht. (Update: Das war durch ES5 der Fall. Ab ES2015 [auch bekannt als ES6] erhält eine mit einem anonymen Ausdruck erstellte Funktion häufig einen wahren Namen [aber keine automatische Kennung], lesen Sie weiter ...)
Namen sind nützlich. Namen können in Stapelspuren, Aufrufstapeln, Listen von Haltepunkten usw. angezeigt werden. Namen sind eine gute Sache ™.
(Früher mussten Sie sich in älteren Versionen von IE [IE8 und darunter] vor benannten Funktionsausdrücken hüten, da diese fälschlicherweise zwei vollständig getrennte Funktionsobjekte zu zwei völlig unterschiedlichen Zeiten erstellt haben [mehr in meinem Blog-Artikel Double take ]. Wenn nötig Unterstützung IE8 [!!], ist es wahrscheinlich am besten mit anonymen Funktion Ausdrücke oder Funktion halten Erklärungen , aber vermeiden sie Funktion Ausdrücke genannt.)
Eine wichtige Sache bei einem benannten Funktionsausdruck ist, dass er einen In-Scope-Bezeichner mit diesem Namen für die Funktion innerhalb des Funktionskörpers erstellt:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
Ab ES2015 erstellen jedoch viele "anonyme" Funktionsausdrücke Funktionen mit Namen, und dies wurde von verschiedenen modernen JavaScript-Engines vorweggenommen, die ziemlich klug darin waren, Namen aus dem Kontext abzuleiten. In ES2015 führt Ihr anonymer Funktionsausdruck zu einer Funktion mit dem Namen boo
. Selbst mit ES2015 + -Semantik wird die automatische Kennung jedoch nicht erstellt:
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();
Die Zuweisung des Funktionsnamens erfolgt mit der abstrakten Operation SetFunctionName, die in verschiedenen Operationen in der Spezifikation verwendet wird.
Die Kurzversion ist im Grunde immer dann, wenn ein anonymer Funktionsausdruck auf der rechten Seite von etwas wie einer Zuweisung oder Initialisierung erscheint, wie:
var boo = function() { /*...*/ };
(oder es könnte sein let
oder const
eher als var
) oder
var obj = {
boo: function() { /*...*/ }
};
oder
doSomething({
boo: function() { /*...*/ }
});
(Die letzten beiden sind wirklich dasselbe) , die resultierende Funktion hat einen Namen ( boo
in den Beispielen).
Es gibt eine wichtige und absichtliche Ausnahme: Zuweisen einer Eigenschaft zu einem vorhandenen Objekt:
obj.boo = function() { /*...*/ }; // <== Does not get a name
Dies war auf Bedenken hinsichtlich Informationslecks zurückzuführen, die beim Hinzufügen der neuen Funktion aufgetreten waren. Details in meiner Antwort auf eine andere Frage hier .