Erläutern Sie die Syntax der gekapselten anonymen Funktion
Zusammenfassung
Können Sie erklären, die Logik hinter der syntax gekapselt anonyme Funktionen in JavaScript? Warum funktioniert das: (function(){})();
aber nicht: function(){}();
?
Was ich weiß,
In JavaScript erstellt man eine benannte Funktion wie diese:
function twoPlusTwo(){
alert(2 + 2);
}
twoPlusTwo();
Können Sie auch eine anonyme Funktion und weisen Sie es einer Variablen:
var twoPlusTwo = function(){
alert(2 + 2);
};
twoPlusTwo();
Können Sie Kapseln sich ein block von code, indem eine anonyme Funktion, dann wickeln Sie es in eckige Klammern und ihn sofort auszuführen:
(function(){
alert(2 + 2);
})();
Dies ist nützlich bei der Erstellung von modularisierten Skripte, um zu vermeiden, überladen den aktuellen Bereich, oder den globalen scope, mit potenziell widersprüchlichen Variablen - wie im Fall von Greasemonkey scripts, jQuery plugins, etc.
Nun verstehe ich, warum das funktioniert. Die Klammern umschließen den Inhalt und setzen Sie nur das Ergebnis (ich bin sicher, es gibt eine bessere Weise, das zu beschreiben), wie mit (2 + 2) === 4
.
Was ich nicht verstehe
Aber ich verstehe nicht, warum dies nicht funktioniert ebenso gut:
function(){
alert(2 + 2);
}();
Können Sie erklären, dass Sie für mich?
InformationsquelleAutor der Frage Premasagar | 2009-10-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es funktioniert nicht, weil es wird analysiert, wie ein
FunctionDeclaration
und der name Bezeichner von Deklarationen ist zwingend.Wenn Sie umgeben Sie es mit Klammern wird ausgewertet, als ein
FunctionExpression
und Funktion Ausdrücken benannt werden kann oder nicht.Grammatik eines
FunctionDeclaration
sieht wie folgt aus:Sowie
FunctionExpression
s:Wie Sie sehen können die
Identifier
(Idopt) token inFunctionExpression
ist optional, daher können wir auch eine Funktion haben Ausdruck ohne einen Namen definiert:Oder namens Funktion Ausdruck:
Den Klammern (formal genannt die Grouping-Operator) umgeben können nur Ausdrücke, und eine Funktion, Ausdruck ausgewertet wird.
Den beiden Grammatik-Produktionen können mehrdeutig sein, und Sie können genau gleich Aussehen, zum Beispiel:
Der parser weiß, ob es ein
FunctionDeclaration
oder eineFunctionExpression
je nach Kontextwo es angezeigt wird.Im obigen Beispiel, das zweite ist ein Ausdruck, weil die Komma-operator kann auch mit nur Ausdrücke.
Auf der anderen Seite
FunctionDeclaration
s könnten tatsächlich erscheinen nur, was heißt "Program
" code, d.h. code, der außerhalb im globalen Bereich und in derFunctionBody
von anderen Funktionen.Funktionen in Blöcke sollten vermieden werden, denn Sie führen ein unberechenbares Verhalten, z.B.:
Der obige code sollte tatsächlich produzieren eine
SyntaxError
da einBlock
können nur Aussagen enthalten (und die ECMAScript-Spezifikation nicht definieren function-Anweisung), aber die meisten Implementierungen sind tolerant, und nimmt einfach die zweite Funktion, die Warnungen'false!'
.Den Mozilla-Implementierungen -Rhino, SpiderMonkey,- haben ein anderes Verhalten. Die Grammatik enthält eine nicht-standard - Function-Anweisung, was bedeutet, dass die Funktion ausgewertet werden, bei Laufzeitnicht zur Analysezeit, wie es geschieht mit
FunctionDeclaration
s. In jenen Implementierungen, werden wir mit der ersten Funktion definiert.Funktionen können deklariert werden, in unterschiedlicher Weise, vergleichen Sie die folgenden:
1 - Eine Funktion definiert, mit der Funktion Konstruktor der Variablen zugewiesen multiplizieren:
2 - Eine Funktion Deklaration einer Funktion mit dem Namen multiplizieren:
3 - Funktion-Ausdruck der Variablen zugewiesen multiplizieren:
4 - Einen benannten Funktions-Ausdruck func_nameder Variablen zugewiesen multiplizieren:
InformationsquelleAutor der Antwort CMS
Obwohl dies ist eine alte Frage und Antwort, es behandelt ein Thema, das an diesem Tag wirft viele Entwickler für eine Schleife. Ich kann nicht zählen die Anzahl der JavaScript-Entwickler-Kandidaten, die ich interviewt habe, die konnte mir nicht sagen, der Unterschied zwischen einer Funktions-Deklaration und eine Funktion Ausdruck undder hatte keine Ahnung, was ein sofort aufgerufen, die Funktion Ausdruck ist.
Erwähnen möchte ich, allerdings eine sehr wichtige Sache ist, dass Premasagar code-snippet, das würde nicht funktionieren, selbst wenn er es gegeben hatte, ein name-Bezeichner.
Dem Grund würde dies nicht funktionieren, ist, dass die JavaScript-engine interpretiert dies als eine Funktions-Deklaration, gefolgt von einer völlig anderen Gruppierung operator, enthält kein Ausdruck, und die Gruppierung der Operatoren muss einen Ausdruck enthalten. Nach JavaScript, das obige code-snippet ist äquivalent zu den folgenden.
Andere Sache, die ich möchte darauf hinweisen, dass Ihnen von nutzen sein kann für einige Menschen ist, dass jeder name Kennung, die Sie für die Funktion Ausdruck ist ziemlich nutzlos im Zusammenhang mit dem Kodex mit Ausnahme von innerhalb der definition der Funktion selbst.
Natürlich mit Namen von Bezeichnern mit Ihrer Funktion Definitionen ist immer hilfreich, wenn es um das Debuggen von code, aber das ist etwas ganz anderes... 🙂
InformationsquelleAutor der Antwort natlee75
In javascript, das heißt Sofort-Invoked Function Expression (IIFE) .
Damit eine Funktion-Ausdruck, den Sie haben:
umschließen Sie es mit ()
Ort ein void-operator, bevor es
es einer Variablen zuweisen.
Sonst wird es behandelt wie die definition einer Funktion und dann werden Sie nicht in der Lage, call - /invoke es in der gleichen Zeit, indem Sie die folgende Weise:
Oben geben Sie Fehler. Da kann man nur eine Funktion aufzurufen Ausdruck sofort.
Dies kann erreicht werden, paar Möglichkeiten:
Weg 1:
Weg 2:
Weg 3:
Weg 4:
Alle oben sofort aufrufen der Funktion Ausdruck.
InformationsquelleAutor der Antwort asmmahmud
Habe ich nur eine weitere kleine Bemerkung. Dein code funktioniert mit kleiner änderung:
Ich den oben genannten syntax anstelle des mehr verbreiteten version:
weil ich es nicht geschafft, den Einzug, um ordnungsgemäß für die javascript-Dateien in vim. Es scheint, dass vim nicht wie die geschweiften Klammern innen offene Klammer.
InformationsquelleAutor der Antwort Andrei Bozantan
Vielleicht die kürzere Antwort wäre, dass
ist ein funktionsliteraldass definiert eine (anonyme) Funktion. Eine zusätzliche ()-paar, das sich als Ausdruck interpretiert, ist nicht zu erwarten, auf oberster Ebene, nur Literale.
ist in einem Ausdruckdass ruft eine anonyme Funktion.
InformationsquelleAutor der Antwort theking2
Oben ist gültige syntax, da alles bestanden innerhalb der Klammer betrachten Sie als Funktion Ausdruck.
Oben ist keine gültige syntax. Da java-script-syntax-parser sucht nach Funktion name nach dem Schlüsselwort function, da Sie nicht alles finden, es gibt eine Fehlermeldung.
InformationsquelleAutor der Antwort Vithy
Können Sie verwendet werden, mit Parameter-Argumente wie
führen würde als 7
InformationsquelleAutor der Antwort Jude
Diese extra-Klammern schafft zusätzliche anonyme Funktionen zwischen den globalen namespace und anonymen Funktion, die den code enthält. Und in Javascript-Funktionen deklariert innerhalb anderer Funktionen können nur auf namespace der übergeordneten Funktion, die Sie enthält. Da gibt es extra Objekt (anonymious Funktion) zwischen Globale Reichweite und der eigentliche code scoping-ist nicht beibehalten.
InformationsquelleAutor der Antwort Jarkko Hietala