2009-03-10 18 views
13

Ich versuche, meinen Kopf um Schließungen zu wickeln (es ist ein Witz es irgendwo in) und ich über das Rennen:JavaScript Umfang und Schließung

(function() { /* do cool stuff */ })(); 

Wie funktionierts? Was ist der Zweck, die Funktion in Parens zu setzen? Warum die leeren Parens danach?

Antwort

30

Der Punkt ist, dass alle Variablen, die im coolen Zeug deklariert sind, nicht im globalen Namespace erstellt werden. Jede Funktion in Javascript wird einen solchen Bereich erstellen. Angenommen, Sie haben Javascript, das Sie ausführen möchten. Wenn Sie dies tun:

var b = 1; 
// stuff using b 

Und einige andere Code verwendet b, es wird Ihren Restwert erhalten. (Oder, noch schlimmer, wenn ein anderer Code b vor der Ausführung Ihres Codes setzt und dann versucht, seinen alten Wert später zu erhalten, hätten Sie ihn zwischenzeitlich geändert.)

Auf der anderen Seite, wenn Sie dies haben Code, der erklärt, und ruft dann die Funktion:

function a() { 
    var b = 1; 
} 

a(); 

und einige andere Code später verwendet b, wird es sehen Ihre Werte nicht, da b auf die Funktion lokal ist. Das Problem dabei ist natürlich, dass du immer noch einen globalen Namen machst - "a", in diesem Fall. Also, wir wollen eine Funktion ohne Namen - deshalb bekommst du den Code, den du beschrieben hast. Er deklariert eine Funktion ohne Namen und ruft sie dann auf.

Leider kann man nicht einfach sagen:

function() { ... }() 

da dies als eine Funktion Erklärung Anweisung und dann einen Syntaxfehler analysiert werden. Wenn Sie die Funktionsdeklaration in Klammern einschließen, erhalten Sie eine Funktion Ausdruck, die dann aufgerufen werden kann. Sie nennen es wie jeden anderen Funktionsausdruck (wie a, oben) und verwenden den zweiten Satz von Parens. Wenn die Funktion beispielsweise Argumente verwendet, übergeben Sie sie dort:

0

Dieses Konstrukt bedeutet eine anonyme Funktion deklarieren und sofort ausführen. Der Grund dafür, dass Sie Ihren Code in einen Funktionskörper einfügen, liegt darin, dass die Variablen, die Sie darin definieren, für die Funktion lokal bleiben und nicht als globale Variablen. Sie sind jedoch weiterhin für die in dieser Funktion definierten Schließungen sichtbar.

1

Die Parens um die Funktion machen deutlich, dass die Funktion ein Ausdruck ist. Die Parens nach sind der Aufruf der Funktion.

Beachten Sie, dass die Funktion keinen Namen hat.

6

Das erstellt eine Funktion, ruft sie auf und verwirft sie.

Es könnte klarer, wenn man es so aussehen:

var throwaway = function(){ 
    // do cool stuff 
}; 
throwaway(); 

dies einen privaten Namensraum zu schaffen gemacht wird. Der Code in der Funktion kann Funktionen und Variablen enthalten, ohne sich Gedanken über einen Konflikt mit anderem auf der Seite geladenem Code machen zu müssen.

+3

Außer natürlich, dass Sie mit dem Namen Ihrer Funktion in Konflikt geraten. –

+2

Äh, ja. Deshalb wird normalerweise mit einer anonymen Funktion gearbeitet. Ich habe gerade eine benannte Funktion verwendet, um eine vertrautere Form zu zeigen, die dasselbe tut. –

+0

jder hat die bessere Antwort, für diejenigen, die zu spät zur Party kommen. – Triptych

0

Wenn Sie die Funktionsdeklaration in parens einfügen, wird ein Ausdruck erstellt, der die anonyme Funktion innerhalb interpretiert. Daher wertet das erste Klammerzeichen eine Funktion aus.

Die "leeren Parens" am Ende rufen die definierte Funktion auf, so dass "// cool stuff" sofort ausgeführt wird.

Dies ist eine Möglichkeit, Code on-the-fly auszuführen und gleichzeitig Variablen außerhalb des globalen Gültigkeitsbereichs zu halten.

Was hier dargestellt wird, hat aber mit Verschlüssen nichts zu tun - zumindest nicht direkt. Bei Closures geht es darum, einen lexikalischen Geltungsbereich beizubehalten, nachdem eine Elternfunktion bereits beendet wurde.

2

Ich bin gerade auf diesen Beitrag vor kurzem gestoßen. Diese Art der Funktionsdefinition & Aufruf heißt selbstaufrufenden Funktionen.

(function(){ //code })(); 

Der Code innerhalb der Funktion wird sofort nach seiner Definition ausgeführt.

1

Ein Schließung Ansatz ist Variablen an die Funktion zu übergeben:

(function($, var_1, var_2) { 
    // use JQuery, var_1 and var_2 as local variables 
})($, var_1, var_2);