Wann möchten Sie in Javascript Folgendes verwenden:
(function(){
//Bunch of code...
})();
darüber:
//Bunch of code...
Wann möchten Sie in Javascript Folgendes verwenden:
(function(){
//Bunch of code...
})();
darüber:
//Bunch of code...
Antworten:
Es geht um variables Scoping. In der selbstausführenden Funktion deklarierte Variablen sind standardmäßig nur für Code innerhalb der selbstausführenden Funktion verfügbar. Auf diese Weise kann Code geschrieben werden, ohne dass es darauf ankommt, wie Variablen in anderen JavaScript-Codeblöcken benannt werden.
Zum Beispiel, wie in einem Kommentar von Alexander erwähnt :
(function() {
var foo = 3;
console.log(foo);
})();
console.log(foo);
Dies wird zuerst protokolliert 3
und dann beim nächsten einen Fehler auslösen, console.log
da dieser foo
nicht definiert ist.
var
, so : ...function(){ foo=3;}
? Es würde eine globale Variable setzen, oder?
function(){ var foo = 3; alert(foo); }; alert(foo);
Also ich verstehe es immer noch nicht
Simpel. So ganz normal aussehend, es ist fast beruhigend:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
Was ist jedoch, wenn ich meiner Seite eine wirklich praktische Javascript-Bibliothek hinzufüge, die erweiterte Zeichen in ihre Darstellungen auf Basisebene übersetzt?
Warte was?
Ich meine, wenn jemand ein Zeichen mit einem Akzent eingibt, aber ich möchte nur 'englische' Zeichen AZ in meinem Programm? Nun ... die spanischen 'ñ' und französischen 'é' Zeichen können in Basiszeichen von 'n' und 'e' übersetzt werden.
Also hat jemand eine nette Person einen umfassenden Zeichenkonverter geschrieben, den ich in meine Site aufnehmen kann ... ich füge ihn hinzu.
Ein Problem: Es enthält eine Funktion namens "Name", die mit meiner Funktion identisch ist.
Dies nennt man Kollision. Wir haben zwei Funktionen im selben Bereich mit demselben Namen deklariert . Das wollen wir vermeiden.
Also müssen wir unseren Code irgendwie erweitern.
Die einzige Möglichkeit, Code in Javascript zu erfassen, besteht darin, ihn in eine Funktion zu verpacken:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Das könnte unser Problem lösen. Alles ist jetzt geschlossen und nur über unsere Öffnungs- und Schließstreben zugänglich.
Wir haben eine Funktion in einer Funktion ... die seltsam anzusehen ist, aber völlig legal.
Nur ein Problem. Unser Code funktioniert nicht. Unsere userName-Variable wird niemals in die Konsole übernommen!
Wir können dieses Problem lösen, indem wir unserer Funktion nach unserem vorhandenen Codeblock einen Aufruf hinzufügen ...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
Oder davor!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Ein sekundäres Problem: Wie hoch ist die Wahrscheinlichkeit, dass der Name 'main' noch nicht verwendet wurde? ... so sehr, sehr schlank.
Wir brauchen mehr Scoping. Und eine Möglichkeit, unsere main () - Funktion automatisch auszuführen.
Jetzt kommen wir zu Funktionen für die automatische Ausführung (oder selbstausführend, selbstlaufend, was auch immer).
((){})();
Die Syntax ist als Sünde umständlich. Es funktioniert jedoch.
Wenn Sie eine Funktionsdefinition in Klammern wickeln und eine Parameterliste ( einen anderen Satz oder Klammern!) Wirkt es als Funktion Anruf .
Schauen wir uns also noch einmal unseren Code mit einer selbstausführenden Syntax an:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
In den meisten Tutorials, die Sie lesen, werden Sie jetzt mit dem Begriff "anonyme Selbstausführung" oder ähnlichem bombardiert.
Nach vielen Jahren der beruflichen Entwicklung, ich stark fordere Sie zu nennen jede Funktion , die Sie schreiben für Debugging - Zwecke.
Wenn etwas schief geht (und es wird), überprüfen Sie die Rückverfolgung in Ihrem Browser. Es ist immer einfacher, Ihre Codeprobleme einzugrenzen, wenn die Einträge im Stack-Trace Namen haben!
Sehr langatmig und ich hoffe es hilft!
:)
Selbstaufruf (auch als automatischer Aufruf bezeichnet) ist, wenn eine Funktion unmittelbar nach ihrer Definition ausgeführt wird. Dies ist ein Kernmuster und dient als Grundlage für viele andere Muster der JavaScript-Entwicklung.
Ich bin ein großer Fan :) davon, weil:
Enorm - (Warum solltest du sagen, dass es gut ist?)
Mehr hier .
Namensraum. Die Bereiche von JavaScript sind auf Funktionsebene.
Ich kann nicht glauben, dass keine der Antworten implizite Globale erwähnt.
Das (function(){})()
Konstrukt schützt nicht vor impliziten Globalen, was für mich das größere Problem ist, siehe http://yuiblog.com/blog/2006/06/01/global-domination/
Grundsätzlich stellt der Funktionsblock sicher, dass alle von Ihnen definierten abhängigen "globalen Variablen" auf Ihr Programm beschränkt sind. Er schützt Sie nicht vor der Definition impliziter globaler Variablen. JSHint oder ähnliches kann Empfehlungen zur Abwehr dieses Verhaltens geben.
Die präzisere var App = {}
Syntax bietet ein ähnliches Schutzniveau und kann auf 'öffentlichen' Seiten in den Funktionsblock eingeschlossen werden. (siehe Ember.js oder SproutCore für reale Welt Beispiele für Bibliotheken , die dieses Konstrukt verwenden)
Soweit private
Eigenschaften gehen, sind sie Art von hoch genug , wenn Sie einen öffentlichen Rahmen oder Bibliothek erstellen, aber wenn man sie umsetzen müssen, Douglas Crockford einige gute Ideen hat.
Ich habe alle Antworten gelesen, hier fehlt etwas sehr Wichtiges , ich werde KÜSSEN. Es gibt zwei Hauptgründe, warum ich selbstausführende anonyme Funktionen oder besser gesagt " Sofort aufgerufener Funktionsausdruck (IIFE) " benötige :
Der erste wurde sehr gut erklärt. Für das zweite studieren Sie bitte folgendes Beispiel:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Achtung 1: Wir weisen keine Funktion zu MyClosureObject
, sondern das Ergebnis des Aufrufs dieser Funktion . Beachten Sie ()
in der letzten Zeile.
Achtung 2: Was Sie zusätzlich über Funktionen in Javascript wissen müssen, ist, dass die inneren Funktionen Zugriff auf die Parameter und Variablen erhalten der Funktionen erhalten, in denen sie definiert sind.
Versuchen wir einige Experimente:
Ich kann es MyName
benutzen getMyName
und es funktioniert:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
Der folgende geniale Ansatz würde nicht funktionieren:
console.log(MyClosureObject.MyName);
// undefined
Aber ich kann einen anderen Namen setzen und das erwartete Ergebnis erhalten:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Bearbeiten: Im obigen Beispiel MyClosureObject
ist die Verwendung ohne new
Präfix vorgesehen, daher sollte es gemäß Konvention nicht großgeschrieben werden.
Gibt es einen Parameter und der "Codebündel" gibt eine Funktion zurück?
var a = function(x) { return function() { document.write(x); } }(something);
Schließung. Der Wert von something
wird von der zugewiesenen Funktion verwendet a
. something
könnte einen variierenden Wert haben (for-Schleife) und jedes Mal, wenn a eine neue Funktion hat.
var x = something;
Funktion in der äußeren Funktion x
als Parameter: imo ist es auf diese Weise besser lesbar ...
x
document.write(something)
Umfang Isolation vielleicht. Damit die Variablen in der Funktionsdeklaration den äußeren Namespace nicht verschmutzen.
Natürlich werden sie es bei der Hälfte der JS-Implementierungen sowieso tun.
Hier ist ein gutes Beispiel dafür, wie eine selbst aufrufende anonyme Funktion nützlich sein kann.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
Ausgabe: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
Ausgabe: 0, 1, 2, 3, 4...
let
anstelle des var
ersten Falles wird alles in Ordnung sein.
Da Funktionen in Javascript erstklassige Objekte sind, definiert es auf diese Weise effektiv eine "Klasse", ähnlich wie C ++ oder C #.
Diese Funktion kann lokale Variablen definieren und Funktionen enthalten. Die internen Funktionen (effektiv Instanzmethoden) haben Zugriff auf die lokalen Variablen (effektiv Instanzvariablen), sind jedoch vom Rest des Skripts isoliert.
Selbstaufgerufene Funktion in Javascript:
Ein selbst aufrufender Ausdruck wird automatisch aufgerufen (gestartet), ohne aufgerufen zu werden. Ein selbst aufrufender Ausdruck wird direkt nach seiner Erstellung aufgerufen. Dies wird im Wesentlichen verwendet, um Namenskonflikte zu vermeiden und um eine Kapselung zu erreichen. Auf die Variablen oder deklarierten Objekte kann außerhalb dieser Funktion nicht zugegriffen werden. Verwenden Sie zur Vermeidung von Minimierungsproblemen (Dateiname.min) immer die selbst ausgeführte Funktion.
Selbstausführende Funktionen werden verwendet, um den Bereich einer Variablen zu verwalten.
Der Bereich einer Variablen ist der Bereich Ihres Programms, in dem sie definiert ist.
Eine globale Variable hat einen globalen Gültigkeitsbereich. Es ist überall in Ihrem JavaScript-Code definiert und kann von überall im Skript aufgerufen werden, auch in Ihren Funktionen. Andererseits werden Variablen, die innerhalb einer Funktion deklariert sind, nur innerhalb des Funktionskörpers definiert. Sie sind lokale Variablen, haben einen lokalen Gültigkeitsbereich und können nur innerhalb dieser Funktion aufgerufen werden. Funktionsparameter gelten auch als lokale Variablen und werden nur innerhalb des Funktionskörpers definiert.
Wie unten gezeigt, können Sie auf die globale Variablenvariable in Ihrer Funktion zugreifen und beachten, dass innerhalb des Funktionskörpers eine lokale Variable Vorrang vor einer globalen Variablen mit demselben Namen hat.
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
Grundsätzlich ermöglicht eine selbstausführende Funktion das Schreiben von Code, ohne sich darum zu kümmern, wie Variablen in anderen Blöcken von Javascript-Code benannt werden.
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
Tatsächlich wird die obige Funktion als Funktionsausdruck ohne Namen behandelt.
Der Hauptzweck des Umschließens einer Funktion in enge und offene Klammern besteht darin, eine Verschmutzung des globalen Raums zu vermeiden.
Die Variablen und Funktionen innerhalb des Funktionsausdrucks wurden privat (dh sie sind außerhalb der Funktion nicht verfügbar.
Die kurze Antwort lautet: Verhinderung der Verschmutzung des globalen (oder höheren) Bereichs.
IIFE (Sofort aufgerufene Funktionsausdrücke) ist die beste Methode zum Schreiben von Skripten als Plug-Ins, Add-Ons, Benutzerskripten oder von Skripten, von denen erwartet wird, dass sie mit Skripten anderer Personen funktionieren . Dies stellt sicher, dass jede von Ihnen definierte Variable keine unerwünschten Auswirkungen auf andere Skripte hat.
Dies ist die andere Möglichkeit, einen IIFE-Ausdruck zu schreiben. Ich persönlich bevorzuge diese folgende Methode:
void function() {
console.log('boo!');
// expected output: "boo!"
}();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
Aus dem obigen Beispiel geht klar hervor, dass IIFE auch die Effizienz und Leistung beeinflussen kann, da die Funktion, von der erwartet wird, dass sie nur einmal ausgeführt wird, einmal ausgeführt und dann endgültig in den Hohlraum geworfen wird . Dies bedeutet, dass die Funktions- oder Methodendeklaration nicht im Speicher verbleibt.
void
. Ich mag das.
Zuerst müssen Sie MDN IIFE besuchen . Nun einige Punkte dazu
Es sieht so aus, als ob diese Frage fertig beantwortet wurde, aber ich werde trotzdem meine Eingabe posten.
Ich weiß, wann ich selbstausführende Funktionen verwenden möchte.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
Mit dieser Funktion kann ich zusätzlichen Code verwenden, um die childObjects-Attribute und -Eigenschaften für saubereren Code zu definieren, z. B. das Festlegen häufig verwendeter Variablen oder das Ausführen mathematischer Gleichungen. Oh! oder Fehlerprüfung. im Gegensatz zu beschränkt auf die Instanziierungssyntax für verschachtelte Objekte von ...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
Das Codieren im Allgemeinen hat viele dunkle Möglichkeiten, viele der gleichen Dinge zu tun, und Sie fragen sich: "Warum sich die Mühe machen?" Es tauchen jedoch immer wieder neue Situationen auf, in denen Sie sich nicht mehr nur auf die Grundprinzipien verlassen können.
Angesichts Ihrer einfachen Frage: "Wann möchten Sie in Javascript Folgendes verwenden: ..."
Ich mag die Antworten von @ken_browning und @ sean_holding, aber hier ist ein weiterer Anwendungsfall, den ich nicht erwähnt sehe:
let red_tree = new Node(10);
(async function () {
for (let i = 0; i < 1000; i++) {
await red_tree.insert(i);
}
})();
console.log('----->red_tree.printInOrder():', red_tree.printInOrder());
Dabei ist Node.insert eine asynchrone Aktion.
Ich kann nicht einfach warten ohne das asynchrone Schlüsselwort bei der Deklaration meiner Funktion aufrufen, und ich brauche keine benannte Funktion für die spätere Verwendung, sondern muss auf diesen Einfügeaufruf warten oder ich brauche einige andere umfangreichere Funktionen (wer weiß?) .
Mit IIRC können Sie private Eigenschaften und Methoden erstellen.