var foo = "hello"; var c = (Funktion a () {Funktion b () {var bar bar = "world"; alert (foo + bar); return bar;} return b;}) () (); alert (foo + c);Dieses Beispiel taucht zweimal Hello World auf;
1. Was ist eine Schließung?
Die "offizielle" Erklärung lautet: Der sogenannte "Verschluss" bezieht sich auf einen Ausdruck (normalerweise eine Funktion), der viele Variablen und eine an diese Variablen gebundene Umgebung aufweist, sodass diese Variablen auch Teil des Ausdrucks sind.
Ich glaube, nur wenige Menschen können diesen Satz direkt verstehen, weil er ihn zu akademisch beschrieben hat. Ich möchte verwenden, wie Sie einen Verschluss in JavaScript erstellen, um Ihnen mitzuteilen, was ein Verschluss ist, da es sehr schwierig ist, die Definition eines Verschlusses direkt zu verstehen, indem Sie den Prozess der Schließung überspringen. Schauen Sie sich den folgenden Code an:
Funktion a () {var i = 0; Funktion b () {alert (++ i);} return b;} var c = a (); c ();Dieser Code hat zwei Merkmale:
1. Die Funktion B ist innerhalb von Funktion A verschachtelt;
2. Funktion A Returns -Funktion b.
Auf diese Weise verweist die Variable c nach der Ausführung von var c = a () tatsächlich auf die Funktion b. Nach der Ausführung von C () wird ein Fenster angezeigt, um den Wert von I anzuzeigen (das erste Mal ist 1). Dieser Code schafft tatsächlich eine Schließung. Warum? Da sich die Variable C -Funktion A auf die Funktion B innerhalb der Funktion A bezieht, dh:
Wenn die interne Funktion b der Funktion a durch eine Variable außerhalb der Funktion A referenziert wird, wird ein Verschluss erzeugt.
Ich denke, Sie verstehen Schließungen immer noch nicht, weil Sie nicht wissen, welche Schließungen haben. Lassen Sie uns weiter unten erkunden.
2. Was ist die Funktion von Schließungen?
Kurz gesagt, die Funktion eines Verschlusses besteht darin, dass nach einer Ausführung und zurückgegebener Verschlüsse der Mechanismus des JavaScript -Müllsammers die Ressourcen, die von A besetzt sind, nicht wiedererlangt, da die Ausführung einer internen Funktion B von A auf die Variablen in A beruhen muss. Dies ist eine sehr einfache Beschreibung der Rolle von Schließungen, die nicht professionell oder streng ist, aber es bedeutet grob, dass dies der Fall ist. Das Verständnis von Schließungen erfordert einen allmählichen Prozess.
Im obigen Beispiel existiert ich nach der Rückgabe der Funktion A immer, sodass ich jedes Mal, wenn C () ausgeführt wird, der Wert von I alarmiert nach dem Hinzufügen von 1.
Dann stellen wir uns eine andere Situation vor. Wenn A nicht funktioniert, ist die Situation völlig anders. Da nach A ausgeführt wurde, wird B nicht in die Außenwelt von A zurückgegeben, sondern nur von A verwiesen, und zu diesem Zeitpunkt wird auf A nur von B verwiesen, sodass die Funktionen A und B auf einander verwiesen werden, aber von der Außenwelt nicht von GC recycelt werden. (Der Mülleimer -Sammelmechanismus von JavaScript wird später ausführlich eingeführt.)
3. Die mikroskopische Welt im Abschluss
Wenn wir ein tieferes Verständnis der Beziehung zwischen Schließungen und Funktion A und der verschachtelten Funktion B haben möchten, müssen wir mehrere andere Konzepte einführen: die Ausführungsumgebung der Funktion (Excisions -Kontext), das aktive Objekt (Call -Objekt), den Umfang (Umfang) und die Bereichskette. Nehmen Sie den Prozess der Funktion A von Definition zur Ausführung als Beispiel, um diese Konzepte zu veranschaulichen.
1. Bei der Definition von Funktion A setzt der JS -Interpreter die Funktionskette A auf die "Umgebung", in der sich A bei der Definition von a befindet. Wenn a eine globale Funktion ist, gibt es nur Fensterobjekte in der Bereichskette.
2. Wenn die Funktion A ausgeführt wird, gilt A in die entsprechende Ausführungsumgebung (Excutution -Kontext).
3. In der Erstellung einer Ausführungsumgebung fügt A zunächst ein Zielferntrieb hinzu, dh den Umfang von A, und sein Wert ist die Umfangskette in Schritt 1. Die Geltungskette von A.Scope = a.
4. Die Ausführungsumgebung erstellt dann ein aktives Objekt (Anrufobjekt). Das aktive Objekt ist auch ein Objekt mit Attributen, hat jedoch keinen Prototyp und kann nicht direkt über JavaScript -Code zugegriffen werden. Fügen Sie nach dem Erstellen des aktiven Objekts das aktive Objekt an die Oberseite der Bereichskette von a hinzu. Zu diesem Zeitpunkt enthält die Umfangskette A zwei Objekte: das aktive Objekt von A und das Fensterobjekt.
5. Der nächste Schritt besteht darin, dem aktiven Objekt ein Argumenteattribut hinzuzufügen, das die übergebenen Parameter speichert, wenn die Funktion a aufgerufen wird.
6. Fügen Sie schließlich alle formalen Parameter der Funktion A und die Verweise auf die interne Funktion B zum aktiven Objekt von a hinzu. In diesem Schritt wird die Definition von Funktion B abgeschlossen, so dass die Funktionsbereichszilonkette B auf die durch b definierte Umgebung eingestellt ist, dh dem Umfang von a.
Zu diesem Zeitpunkt wird die gesamte Funktion a von der Definition bis zur Ausführung erfüllt. Zu diesem Zeitpunkt gibt A einen Verweis auf Funktion B auf C zurück, und die Bereichskette von Funktion B enthält einen Verweis auf das aktive Objekt der Funktion A, dh B kann auf alle in a definierten Variablen und Funktionen zugreifen. Die Funktion B wird durch C verwiesen, und die Funktion B stützt sich auf Funktion A, sodass die Funktion A nach seiner Rückgabe von GC nicht recycelt wird.
Wenn die Funktion B ausgeführt wird, ist es auch über die gleiche wie oben. Daher enthält die Zielfernrohrkette von B während der Ausführung 3 Objekte: das aktive Objekt von B, das aktive Objekt von A und das Fensterobjekt, wie in der folgenden Abbildung gezeigt:
Wie in der Abbildung gezeigt, wird beim Zugriff auf eine Variable in Funktion B die Suchreihenfolge zuerst nach einem eigenen aktiven Objekt suchen. Wenn sie existiert, wird sie zurückgegeben. Wenn es nicht existiert, sucht es weiterhin nach dem aktiven Objekt der Funktion a und sucht nacheinander, bis es gefunden wird. Wenn es in der gesamten Bereichskette nicht gefunden werden kann, wird undefiniert zurückgegeben. Wenn es ein Prototyp -Prototyp -Objekt für Funktion B gibt, suchen Sie nach der Suche nach einem eigenen aktiven Objekt zuerst nach einem eigenen Prototyp -Objekt und suchen Sie dann weiter. Dies ist der variable Suchmechanismus in JavaScript.
4. Anwendungsszenarien von Schließungen
1. Schützen Sie die Sicherheit von Variablen in der Funktion. Wenn ich das erste Beispiel als Beispiel in Funktion A nehme, kann ich nur mit Funktion B zugegriffen werden, kann aber nicht über andere Kanäle zugegriffen werden, wodurch die Sicherheit von i geschützt wird.
2. Halten Sie eine Variable im Speicher bei. Nach wie vor wie zuvor existiere ich aufgrund des Verschlusses immer im Speicher, sodass ich jedes Mal, wenn C () ausgeführt wird, 1 hinzugefügt wird 1.
Die obigen zwei Punkte sind die grundlegendsten Anwendungsszenarien für Verschlüsse, und viele klassische Fälle stammen davon.
5. JavaScripts Müllsammlermechanismus
In JavaScript wird das Objekt von GC recycelt, wenn ein Objekt nicht mehr verwiesen wird. Wenn zwei Objekte auf einander Bezug genommen werden und von der dritten Person nicht mehr verwiesen werden, werden die beiden Objekte aufeinander recycelt. Da auf die Funktion A durch B verwiesen wird, wird B von C außerhalb von A verwiesen, weshalb die Funktion A nach der Ausführung nicht recycelt wird.
Der obige Artikel versteht, dass der Verschlussmechanismus der gesamte Inhalt ist, den ich mit Ihnen teile. Ich hoffe, Sie können Ihnen eine Referenz geben und ich hoffe, Sie können wulin.com mehr unterstützen.