Zusamenfassend
Zusammenfassung
In ihrer einfachsten Form zielt diese Technik darauf ab, Code in einen Funktionsbereich einzubinden .
Es hilft, die Chancen zu verringern von:
- Kollision mit anderen Anwendungen / Bibliotheken
- Verschmutzung überlegener (weltweit wahrscheinlichster) Anwendungsbereich
Es ist nicht festzustellen , wann das Dokument fertig ist - es ist nicht irgendeine Art von document.onload
nochwindow.onload
Es ist allgemein als Immediately Invoked Function Expression (IIFE)
oder bekannt Self Executing Anonymous Function
.
Code erklärt
var someFunction = function(){ console.log('wagwan!'); };
(function() { /* function scope starts here */
console.log('start of IIFE');
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})(); /* function scope ends */
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Im obigen Beispiel ist jede in der Funktion definierte Variable (dh deklariert mit var
) "privat" und NUR innerhalb des Funktionsumfangs zugänglich (wie Vivin Paliath es ausdrückt). Mit anderen Worten, diese Variablen sind außerhalb der Funktion nicht sichtbar / erreichbar. Siehe Live-Demo .
Javascript hat Funktionsumfang. "In einer Funktion definierte Parameter und Variablen sind außerhalb der Funktion nicht sichtbar, und eine an einer beliebigen Stelle innerhalb einer Funktion definierte Variable ist überall in der Funktion sichtbar." (aus "Javascript: The Good Parts").
Mehr Details
Alternativer Code
Am Ende könnte der zuvor veröffentlichte Code auch wie folgt ausgeführt werden:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
};
myMainFunction(); // I CALL "myMainFunction" FUNCTION HERE
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Siehe Live-Demo .
Die Wurzeln
Iteration 1
Eines Tages dachte wahrscheinlich jemand: "Es muss eine Möglichkeit geben, die Benennung von 'myMainFunction' zu vermeiden, da wir sie nur sofort ausführen möchten."
Wenn Sie zu den Grundlagen zurückkehren, stellen Sie Folgendes fest:
expression
: etwas, das einen Wert ergibt. dh3+11/x
statement
: Codezeile (n), die etwas tun, ABER es wird kein Wert ausgewertet. dhif(){}
In ähnlicher Weise werden Funktionsausdrücke zu einem Wert ausgewertet. Und eine Konsequenz (nehme ich an?) Ist, dass sie sofort aufgerufen werden können:
var italianSayinSomething = function(){ console.log('mamamia!'); }();
So wird unser komplexeres Beispiel:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
}();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Siehe Live-Demo .
Iteration 2
Der nächste Schritt ist der Gedanke "Warum haben, var myMainFunction =
wenn wir es nicht einmal benutzen!?".
Die Antwort ist einfach: Versuchen Sie, dies zu entfernen, wie unten:
function(){ console.log('mamamia!'); }();
Siehe Live-Demo .
Es wird nicht funktionieren, weil "Funktionsdeklarationen nicht aufrufbar sind" .
Der Trick besteht darin, dass var myMainFunction =
wir durch Entfernen den Funktionsausdruck in eine Funktionsdeklaration umgewandelt haben . Weitere Informationen hierzu finden Sie unter den Links unter "Ressourcen".
Die nächste Frage lautet: "Warum kann ich es nicht als Funktionsausdruck mit etwas anderem als behalten var myMainFunction =
?
Die Antwort lautet "Sie können", und es gibt tatsächlich viele Möglichkeiten, wie Sie dies tun können: Hinzufügen von a +
, a !
, a -
oder vielleicht in Klammern setzen (wie es jetzt durch Konvention geschieht), und mehr, glaube ich. Zum Beispiel:
(function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.
oder
+function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console
oder
-function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console
Sobald die relevante Änderung zu unserem früheren "alternativen Code" hinzugefügt wurde, kehren wir zu genau demselben Code zurück, der im Beispiel "Code Explained" verwendet wurde
var someFunction = function(){ console.log('wagwan!'); };
(function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Lesen Sie mehr über Expressions vs Statements
:
Bereiche entmystifizieren
Eine Sache, die man sich fragen könnte, ist: "Was passiert, wenn Sie die Variable NICHT 'richtig' innerhalb der Funktion definieren - dh stattdessen eine einfache Zuweisung vornehmen?"
(function() {
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
myOtherFunction = function(){ /* oops, an assignment instead of a declaration */
console.log('haha. got ya!');
};
})();
myOtherFunction(); // reachable, hence works: see in the console
window.myOtherFunction(); // works in the browser, myOtherFunction is then in the global scope
myFunction(); // unreachable, will throw an error, see in the console
Siehe Live-Demo .
Wenn einer Variablen, die nicht in ihrem aktuellen Bereich deklariert wurde, ein Wert zugewiesen wird, wird "die Bereichskette nachgeschlagen, bis sie die Variable findet oder den globalen Bereich erreicht (an welchem Punkt sie erstellt wird)".
In einer Browserumgebung (im Vergleich zu einer Serverumgebung wie nodejs) wird der globale Bereich durch das window
Objekt definiert . Daher können wir tun window.myOtherFunction()
.
Mein "Good Practices" -Tipp zu diesem Thema lautet: Verwenden Sie immer, var
wenn Sie etwas definieren : ob es sich um eine Zahl, ein Objekt oder eine Funktion handelt, und selbst wenn Sie sich im globalen Bereich befinden. Dies macht den Code viel einfacher.
Hinweis:
- Javascript ist nicht hat
block scope
(Update: Block Umfang lokale in dem Nachspiel Variablen ES6 .)
- Javascript hat nur
function scope
& global scope
( window
Gültigkeitsbereich in einer Browser-Umgebung)
Lesen Sie mehr über Javascript Scopes
:
Ressourcen
Nächste Schritte
Sobald Sie dieses IIFE
Konzept erhalten haben, führt es zu dem module pattern
, was üblicherweise durch Nutzung dieses IIFE-Musters erfolgt. Habe Spaß :)