Früher wusste ich, was das bedeutet, aber ich kämpfe jetzt …
Ist das im Grunde gesagt document.onload
?
(function () {
})();
Ausfahrten
Früher wusste ich, was das bedeutet, aber ich kämpfe jetzt …
Ist das im Grunde gesagt document.onload
?
(function () {
})();
gion_13
Es ist ein Sofort aufgerufener Funktionsausdruckoder IIFE kurz. Es wird sofort nach seiner Erstellung ausgeführt.
Es hat nichts mit einem Event-Handler für irgendwelche Events (wie z document.onload
).
Betrachten Sie den Teil innerhalb des ersten Klammerpaars: (function(){})();
….es ist ein regulärer Funktionsausdruck. Dann schauen Sie sich das letzte Paar an (function(){})();
, dies wird normalerweise zu einem Ausdruck hinzugefügt, um eine Funktion aufzurufen; in diesem Fall unser vorheriger Ausdruck.
Dieses Muster wird häufig verwendet, wenn versucht wird, eine Verschmutzung des globalen Namensraums zu vermeiden, da alle Variablen, die innerhalb des IIFE (wie in jedem anderen normal Funktion) sind außerhalb ihres Bereichs nicht sichtbar.
Aus diesem Grund haben Sie diese Konstruktion möglicherweise mit einem Event-Handler für verwechselt window.onload
weil es oft so verwendet wird:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Von Guffa vorgeschlagene Korrektur:
Die Funktion wird direkt nach ihrer Erstellung ausgeführt, nicht nachdem sie geparst wurde. Der gesamte Skriptblock wird analysiert, bevor darin enthaltener Code ausgeführt wird. Außerdem bedeutet das Analysieren von Code nicht automatisch, dass er ausgeführt wird. Wenn sich beispielsweise das IIFE in einer Funktion befindet, wird es nicht ausgeführt, bis die Funktion aufgerufen wird.
Aktualisieren
Da dies ein ziemlich beliebtes Thema ist, ist es erwähnenswert, dass auch IIFEs geschrieben werden können Die Pfeilfunktion von ES6 (wie Gajus in einem Kommentar darauf hingewiesen hat):
((foo) => {
// do something with foo here foo
})('foo value')
@gion_13 Was ist der Unterschied zwischen der Erstellungsphase und der Analysephase?
– ein Kantowort
28. März 2016 um 18:31 Uhr
@jlei So wie ich es sehe, umfasst der Lebenszyklus eines js-Programms die folgenden Phasen: Analyse, Erstellung / Kompilierung, Ausführung. Obwohl die tatsächliche Implementierung (und Benennung :)) ) von Browser zu Browser unterschiedlich sein kann, können wir diese Phasen in unserem Code bestimmen, indem wir auf Parsing-Fehler, Hub- und Laufzeitfehler achten. Ich persönlich habe nicht viele Ressourcen dazu gefunden, weil es zu niedrig ist und der Programmierer es nicht kontrollieren kann. Eine Art Erklärung finden Sie in diesem SO-Beitrag: stackoverflow.com/a/34562772/491075
– gion_13
29. März 2016 um 5:45 Uhr
@sam firat von allen, es gibt die varianle-Deklaration und das neue Schlüsselwort. Dies bedeutet, dass Sie in Ihrem Beispiel ein neues Objekt instanziieren, das durch seinen Konstruktor (anonymer Funktionsausdruck) definiert und über den new-Operator aufgerufen wird, nicht durch Aufrufen der Funktion wie im IIFE-Beispiel. Sicher, diese Funktion wirkt wie ein Abschluss für ihren Inhalt, aber es ist bei weitem ein anderer Anwendungsfall.
– gion_13
30. Januar 2017 um 6:13 Uhr
@Pankaj — Für sich genommen, das ist nicht einmal syntaktisch gültiges JS (es ist ein Funktionsausdruck, aber nicht im Ausdruckskontext, wird also als Syntaxfehler behandelt).
– QUentin
9. Oktober 2018 um 10:46 Uhr
Es ist wichtig anzumerken, dass IFFE’s nützlich waren wegen der var
Schlüsselwort, das einen globalen Geltungsbereich hatte. Daher mussten JS-Entwickler einen Weg finden, Variablen in ihrem Code zu „begrenzen“.
– der ProCoder
8. Oktober 2021 um 14:07 Uhr
Guffa
Es ist nur eine anonyme Funktion, die direkt nach ihrer Erstellung ausgeführt wird.
Es ist so, als ob Sie es einer Variablen zuweisen und es direkt danach verwenden würden, nur ohne die Variable:
var f = function () {
};
f();
In jQuery gibt es ein ähnliches Konstrukt, an das Sie vielleicht denken:
$(function(){
});
Das ist die Kurzform der Bindung ready
Veranstaltung:
$(document).ready(function(){
});
Aber die beiden obigen Konstrukte sind es nicht IIFES.
Die letzten beiden sind nicht wirklich IIFEs, da sie aufgerufen werden, wenn das DOM bereit ist und nicht sofort
– svvac
22. Mai 2014 um 11:48 Uhr
@swordofpain: Ja, das ist richtig, sie sind keine IIFEs.
– Gufa
22. Mai 2014 um 17:04 Uhr
@swordofpain unter Berücksichtigung des zweiten Ausschnitts; Würde es einen Wert in add () am Ende der Funktion geben, indem es in ein IIFE umgewandelt wird?
– Zeitbandit
25. Juli 2015 um 13:53 Uhr
Ist das Semikolon am Ende notwendig?
– FrenkyB
31. März 2017 um 12:09 Uhr
@FrenkyB Nicht erforderlich, nein, aber empfohlen (Semikolons sind in Javascript häufig nicht unbedingt erforderlich, aber es ist eine gute Übung). All dies sind Anweisungen, die anonyme Funktionen enthalten, anstatt Funktionsdeklarationen zu sein.
– Ledivin
20. Juni 2017 um 17:41 Uhr
令狐葱
Ein sofort aufgerufener Funktionsausdruck (IIFE) ruft sofort eine Funktion auf. Das bedeutet einfach, dass die Funktion unmittelbar nach Abschluss der Definition ausgeführt wird.
Drei weitere gebräuchliche Formulierungen:
// Crockford's preference - parens on the inside
(function() {
console.log('Welcome to the Internet. Please follow me.');
}());
//The OPs example, parentheses on the outside
(function() {
console.log('Welcome to the Internet. Please follow me.');
})();
//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
console.log('Welcome to the Internet. Please follow me.');
}();
Wenn es keine besonderen Anforderungen an den Rückgabewert gibt, können wir schreiben:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Alternativ kann es sein:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
Du kannst sogar schreiben:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
Letzter 31.new
‘ ist eine ungültige Syntax
– Katze
1. März 2016 um 2:39 Uhr
Warum gibt es so viele Möglichkeiten, dasselbe zu schreiben?!! >_< Ich mag diese Sprache nicht
– Awesome_girl
23. Juni 2016 um 14:33 Uhr
uuund der Gewinner ist ;(function(){}());
– Roko C. Buljan
27. März 2017 um 23:45 Uhr
@Awesome_girl: Es gibt nicht viele Möglichkeiten, dasselbe zu schreiben; Es ist so, dass JS ein loses Typsystem mit Operatoren hat, die mit jedem Werttyp arbeiten können. Du kannst tun 1 - 1
und Sie können es genauso einfach tun true - function(){}
. Es ist nur eine Sache (ein Infix-Subtraktionsoperator), aber mit anderen, sogar unsinnigen Operanden.
– Benutzer9274775
3. Februar 2018 um 18:37 Uhr
Was ist der Vorteil der Verwendung von Crockfords Funktion (function(){}()) gegenüber den anderen?
– Robert Roche
7. Mai 2018 um 15:47 Uhr
Usmann
Dieses Konstrukt heißt an Sofort aufgerufener Funktionsausdruck (IIFE) was bedeutet, dass es sofort ausgeführt wird. Stellen Sie sich das als eine Funktion vor, die automatisch aufgerufen wird, wenn der Interpreter diese Funktion erreicht.
Häufigster Anwendungsfall:
Einer der häufigsten Anwendungsfälle besteht darin, den Gültigkeitsbereich einer Variablen einzuschränken, die über erstellt wurde var
. Variablen erstellt über var
haben einen auf eine Funktion beschränkten Gültigkeitsbereich, sodass dieses Konstrukt (das ein Funktionswrapper um bestimmten Code ist) sicherstellt, dass Ihr Variablenbereich nicht aus dieser Funktion herausleckt.
Im folgenden Beispiel count
wird nicht außerhalb der sofort aufgerufenen Funktion verfügbar sein, dh im Geltungsbereich von count
wird nicht aus der Funktion lecken. Sie sollten eine bekommen ReferenceError
sollten Sie trotzdem versuchen, außerhalb der sofort aufgerufenen Funktion darauf zuzugreifen.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
ES6-Alternative (empfohlen)
In ES6 können wir jetzt Variablen über erstellen lassen let
und const
. Beide sind blockbezogen (im Gegensatz zu var
die funktionsbezogen ist).
Anstatt dieses komplexe Konstrukt von IIFE für den oben erwähnten Anwendungsfall zu verwenden, können Sie daher jetzt viel einfacheren Code schreiben, um sicherzustellen, dass der Gültigkeitsbereich einer Variablen nicht aus Ihrem gewünschten Block austritt.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
In diesem Beispiel haben wir verwendet let
definieren count
Variable, die macht count
beschränkt auf den Codeblock, den wir mit den geschweiften Klammern erstellt haben {...}
.
Ich nenne es ein „lockiges Gefängnis“.
Solendil
Es deklariert eine anonyme Funktion und ruft sie dann auf:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
Ich denke, “Argumente” sind äußere Variablen, auf die als “arg” verwiesen wird, um im lokalen Kontext innerhalb der Funktion verwendet zu werden?
– Dalibor
25. März 2015 um 8:35 Uhr
@Dalibor arguments
ist Besondere; Ich vermute, der Antwortende hat gerade umgedreht, wohin die Namen gehen
– Katze
1. März 2016 um 2:36 Uhr
Gemeinschaft
Das heißt sofort ausführen.
also wenn ich das mache:
var val = (function(){
var a = 0; // in the scope of this function
return function(x){
a += x;
return a;
};
})();
alert(val(10)); //10
alert(val(11)); //21
Geige: http://jsfiddle.net/maniator/LqvpQ/
var val = (function(){
return 13 + 5;
})();
alert(val); //18
Ich denke, “Argumente” sind äußere Variablen, auf die als “arg” verwiesen wird, um im lokalen Kontext innerhalb der Funktion verwendet zu werden?
– Dalibor
25. März 2015 um 8:35 Uhr
@Dalibor arguments
ist Besondere; Ich vermute, der Antwortende hat gerade umgedreht, wohin die Namen gehen
– Katze
1. März 2016 um 2:36 Uhr
Scott Martin
(function () {
})();
Dies wird IIFE (Immediately Invoked Function Expression) genannt. Es ist eines der berühmten JavaScript-Designmuster und das Herz und die Seele des modernen Modulmusters. Wie der Name schon sagt, wird es sofort nach seiner Erstellung ausgeführt. Dieses Muster schafft einen isolierten oder privaten Ausführungsbereich.
JavaScript vor ECMAScript 6 verwendete lexikalisches Scoping, daher wurde IIFE zum Simulieren von Block Scoping verwendet. (Mit ECMAScript 6 ist Block Scoping mit der Einführung des let
und const
Schlüsselwörter.)
Referenz für Probleme mit lexikalischem Scoping
Simulieren Sie das Block-Scoping mit IIFE
Der Leistungsvorteil der Verwendung von IIFEs ist die Fähigkeit, häufig verwendete globale Objekte wie z window
, document
, usw. als Argument, indem Sie die Bereichssuche reduzieren. (Denken Sie daran, dass JavaScript nach Eigenschaften im lokalen Geltungsbereich und weit oben in der Kette bis zum globalen Geltungsbereich sucht). Der Zugriff auf globale Objekte im lokalen Bereich reduziert also die Suchzeit wie unten.
(function (globalObj) {
//Access the globalObj
})(window);
Vielen Dank, dass Sie das Wesentliche zum Verständnis der zweiten Klammer in IIFE bereitgestellt haben. Auch zur Verdeutlichung des Suchzeitvorteils der globalen Variablen, indem sie in der Definition definiert werden
– Arsal
19. April 2017 um 8:16 Uhr
Übrigens, obwohl Sie Leute sehen werden, die diese Funktion “selbstaufrufend” nennen, ist das eindeutig nicht wahr. Der Begriff life hat den Vorteil der Genauigkeit.
– AakashM
22. November 2011 um 14:43 Uhr
Dies gibt eine großartige Erklärung für dieses Konstrukt. Hier entstand auch der Begriff „IIFE“. benalman.com/news/2010/11/…
– jeremysawesome
5. Januar 2012 um 15:33 Uhr
mögliches Duplikat von Was genau ist der Sinn dieses Funktionskonstrukts? Warum wird es benötigt?
– Josh Mein
20. November 2013 um 13:50 Uhr
Zur Benennung dieses Konstrukts siehe auch hier. Lesen Sie mehr über den Zweck dieses Konstrukts und eine technische Erklärung (auch hier). Sehen Sie sich für die Syntax an, warum die Klammern notwendig sind und wo sie hingehört.
– Bergi
16. Juli 2014 um 22:33 Uhr
stackoverflow.com/questions/2421911/…
– Adrien Be
28. Juli 2014 um 8:01 Uhr