2010-11-18 3 views
53

Oft sehe ich den folgenden Code:Init-Funktion in JavaScript und wie es funktioniert

(function() { 
    // init part 
})(); 

aber ich konnte nie meinen Kopf um, wie es funktioniert. Ich finde die letzten Klammern besonders verwirrend. Kann jemand erklären, wie es in Bezug auf Ausführungskontexte (EC) und variable Objekte (VO) funktioniert?

+2

sind Sie an einer "formalen Erklärung" interessiert, in Bezug auf die ECMA-262-Spezifikation? – CMS

+1

Lesen Sie über den [Zweck dieses Konstrukts] (http://stackoverflow.com/q/592396/1048572). Werfen Sie einen Blick auf eine nicht-technische [Erklärung] (http://stackoverflow.com/q/8228281/1048572), auch [hier] (http://stackoverflow.com/a/441498/1048572). Für die Syntax siehe [warum die Klammern erforderlich sind] (http://stackoverflow.com/q/1634268/1048572) und [wohin sie gehen sollten] (http://stackoverflow.com/q/3384504/1048572) . – Bergi

Antwort

46

Dieses Muster erzeugt einen neuen Ausführungskontext (EC), in dem alle lokalen Variablenobjekte (VOs) leben werden, und wird ebenfalls absterben, wenn die EC beendet wird. Die einzige Ausnahme zu dieser Lebenszeit sind VOs, die Teil einer closure werden.

Bitte beachten Sie, dass JavaScript keine magische "init" -Funktion hat. Sie könnten dieses Muster mit solch einem Muster assoziieren, da die meisten JS-Bibliotheken (jQuery, YUI usw.), die sich selbst respektieren, dies tun, damit sie das globale NS nicht mehr als nötig verschmutzen.

Eine Demonstration:

var x = 1; // global VO 
(function(){   
    var x = 2; // local VO 
})(); 
x == 1; // global VO, unchanged by the local VO 

Der 2. Satz von „Klammern“ (das sind Pars tatsächlich aufgerufen, oder eine Reihe von Klammern), sind einfach die Funktionsausdruck direkt es vorhergehenden aufzurufen (wie durch die definierte vorheriger Klammersatz).

+7

Nun, wenn Sie erklärt haben, was ein EC und VO für Entwickler sind, die das nicht verstehen, dann hätte ich Ihnen eine Up-Abstimmung gegeben, aber statt einer vollständigen Antwort, für die ich vielleicht Google-Akronyme verwenden muss. –

+14

Ich habe EC und VO nicht definiert, da die ursprüngliche Frage Definitionen für diese enthielt. Wenn Sie also die Frage lesen, sollten Sie bereits wissen, was sie bedeuten;) Diese beiden Seiten können Ihnen auch helfen, die Variablen besser zu verstehen : 1. http://jibbering.com/faq/ 2. http://jibbering.com/faq/notes/closures/ – ken

+0

@ken danke für die Links – Chris22

26

Der Code erstellt eine anonyme Funktion und führt sie dann sofort aus. Ähnlich wie:

var temp = function() { 
    // init part 
} 
temp(); 

Der Zweck dieser Konstruktion besteht darin, einen Bereich für den Code innerhalb der Funktion zu erstellen. Sie können Variablen und Funktionen innerhalb des Bereichs deklarieren, und diese sind für diesen Bereich lokal. Auf diese Weise wird der globale Geltungsbereich nicht durcheinander gebracht, wodurch das Risiko von Konflikten mit anderen Skripts minimiert wird.

+0

Hochachtungsvoll, für diejenigen unter Ihnen, die diese Antwort weiter auffrischen, beantwortet die gegebene Lösung keine der Fragen, die das OP * überhaupt gestellt hat *. Er fragt nach den letzten Klammern [sic] und wie sich der angegebene Code auf EC's und VO's bezieht ... was von Guffa zur Verfügung gestellt wurde, sieht aus wie die normale anonyme Funktion, die nicht auf die spezifischen Punkte eingeht das OP bringt auf. – ken

+3

@ken: Die Leute scheinen zu mögen, wie ich erkläre, was der Code tut und warum er benutzt wird. Nur weil ich nicht die genauen Bedingungen verwende, die du tust, mache ich es nicht falsch. – Guffa

+0

Ich habe nie gesagt, es war/falsch /, Ich habe nur darauf hingewiesen, dass Ihre Copy/Paste-Antwort nicht berücksichtigt, was das OP fragte, das ist alles. – ken

78

Die Art, wie ich dies normalerweise den Leuten erklärt, ist zu zeigen, wie es mit anderen JavaScript-Mustern vergleichbar ist.

Zunächst sollten Sie wissen, dass es zwei Möglichkeiten, eine Funktion zu deklarieren (eigentlich gibt es mindestens fünf, aber diese sind die beiden Hauptschuldigen):

function foo() {/*code*/}

und

var foo = function() {/*code*/};

Auch wenn diese Konstruktion seltsam aussieht, verwenden Sie sie wahrscheinlich immer beim Anhängen von Ereignissen:

sollten Sie beachten, dass die zweite Form von einer regulären Variablendeklaration ist nicht viel anders:

var bar = 5; 
var baz = 'some string'; 
var foo = function() {/*code*/}; 

Aber in JavaScript, um Sie immer die Wahl haben einen Wert direkt oder über eine Variable zwischen der Verwendung. Wenn bar5 ist, dann werden die nächsten beiden Aussagen sind äquivalent:

var myVal = bar * 100; // use 'bar' 
var myVal = 5 * 100; // don't use 'bar' 

Nun, wenn Sie 5 auf eigene verwenden können, warum können Sie function() {\*code*\} nicht zu sehr auf seine eigene benutzen? In der Tat können Sie. Und das nennt man eine anonyme Funktion.Also diese zwei Beispiele sind gleichwertig:

Der einzige Unterschied, den Sie sehen sollten, ist in den zusätzlichen Klammern. Das liegt einfach daran, dass wenn Sie eine Zeile mit dem Schlüsselwort function starten, der Parser denkt, dass Sie eine Funktion deklarieren, indem Sie das erste Muster am Anfang dieser Antwort verwenden, und eine Syntaxfehlerausnahme auslösen. Umhüllen Sie also Ihre gesamte anonyme Funktion in zwei geschweifte Klammern und das Problem verschwindet.

Mit anderen Worten sind die folgenden drei Aussagen gültig:

5;      // pointless and stupid 
'some string';   // pointless and stupid 
(function(){/*code*/}()); // wonderfully powerful 
+2

"Die Art und Weise, wie ich dies den Menschen normalerweise erklären, ist zu zeigen, wie Es ist vergleichbar mit anderen JavaScript-Mustern. " Es war unglaublich hilfreich, also danke, dass du dir Zeit genommen hast und das getan hast :) – NessDan

+0

Ich denke, du hast getippt (function() {/ * code * /}()); Sie wollten (function() {/ * code * /})() eingeben. Richtig? – RayLoveless

+0

Nein, aber das macht nichts. Douglas Crockford empfiehlt die Form, die ich verwendet habe, während viele Leute deine empfehlen. Siehe http://stackoverflow.com/questions/3783007/is-there-a-difference-with-function-and-function. Wie dem auch sei, der Grund für Parens ist, dass Sie vermeiden, die Anweisung mit 'function' zu starten (Sie könnten also genauso einfach'! Function() {/ * code * /}() 'oder' -function () {/ * code * /}() '. Ich mag nicht alles, was Crockford empfiehlt, aber ich denke, seine strenge Konsistenz ist besser als die Alternative von jedermann-tun-was-du-willst und sein Linting-Tool (JSLint) erfordert es. – Andrew

14

Ich kann niemand nicht glauben, dass die ops Frage beantwortet hat!

Die letzten Klammern werden verwendet, um die Parameter an die anonyme Funktion zu übergeben. So erzeugt das folgende Beispiel eine Funktion, läuft es dann mit den x = 5 und y = 8

(function(x,y){ 
    //code here 
})(5,8) 

Dies kann nicht so nützlich erscheinen, aber es hat seinen Platz. Die häufigste ich gesehen habe, ist

(function($){ 
    //code here 
})(jQuery) 

die für jQuery im kompatibelen Modus sein kann, aber Sie können in der anonymen Funktion, um es als „$“ beziehen.

+1

Dies kann auch die Leistung durch Verkürzen der [Scope-Kette] (http://jibbering.com/faq/notes/closures/) für diese bestimmte Variable verbessern. – ken

1

In einfachen Wort kann man das verstehen, wenn Laden der Seite, die von diesem zweiten Paar Klammern() Funktion aufgerufen rufen müssen nicht haben wird default.We die function.It als anonyme Funktion bekannt.

d.h.

(function(a,b){ 
//Do your code here 
})(1,2); 

Es gleichen wie als

var test = function(x,y) { 
    // Do your code here 
} 
test(1,2); 
1

Seine immediatly genannt Aufruf Funktionsausdruck (IIFE). Hauptsächlich mit dem JavaScript-Schließungskonzept verbunden. Die Hauptfunktion besteht darin, die Funktion vor der Änderung der globalen Variablen auszuführen, damit das erwartete Verhalten des Codes beibehalten werden kann.

+0

Und hier ist ein Link: https://en.wikipedia.org/wiki/Integrierte_Funktionsausdruck – Luke

Verwandte Themen