Vorwort: Es ist immer noch ein Einführungsartikel. JavaScript gibt es mehrere sehr wichtige Sprachmerkmale - Objekte, Prototyp -Vererbung und Schließungen. Unter ihnen sind Verschlüsse eine neue Sprachfunktion für Programmierer, die die traditionelle statische Sprache C/C ++ verwenden. Dieser Artikel beginnt mit Beispielen, um die Sprachmerkmale von JavaScript -Verschlüssen einzuführen und einige ECMAScript -Sprachspezifikationen zu kombinieren, damit die Leser Verschlüsse tiefer verstehen können.
Hinweis: Dieser Artikel ist ein Einführungsartikel, und die Beispielmaterialien werden im Internet zusammengestellt. Wenn Sie ein Meister sind, können Sie gerne technische Vorschläge und Meinungen zum Artikel vorlegen. In diesem Artikel wird JavaScript erörtert, und Sie möchten keine Sprachen vergleichen. Wenn Sie mit JavaScript von Natur aus unangenehm sind, machen Sie bitte einen Umweg.
Was ist eine Schließung?
Was ist eine Schließung? Der Verschluss ist Verschluss, eine neue Funktion, die statische Sprachen nicht haben. Schließungen sind jedoch nicht so kompliziert, dass sie unverständlich sind. Kurz gesagt, Schließungen sind:
Verschlüsse sind die lokale Variablen der Funktion, aber diese lokalen Variablen existieren weiterhin nach Rückkehr der Funktion.
Schließungen sind der "Stapel" der Funktion und werden nach Rückkehr der Funktion nicht freigegeben. Wir können auch verstehen, dass diese Funktionsstapel nicht auf dem Stapel zugewiesen, sondern auf dem Haufen zugewiesen werden.
Bei der Definition einer anderen Funktion innerhalb einer Funktion wird ein Verschluss erzeugt
Die obige zweite Definition ist die erste ergänzende Beschreibung, die das Objekt des Subjekts der ersten Definition extrahiert - der Verschluss ist ein Satz von „lokalen Variablen“ der Funktion. Es ist nur so, dass auf diese lokale Variable nach der Rückkehr der Funktion zugegriffen werden kann. (Dies ist keine offizielle Definition, aber diese Definition sollte für Ihr Verständnis von Schließungen förderlicher sein.)
Als lokale Variablen können durch den Code in der Funktion zugegriffen werden, und es gibt keinen Unterschied zwischen dieser und statischen Sprache. Der Unterschied zwischen den Schließungen besteht darin, dass auf lokale Variablen nach der Ausführung der Funktion weiterhin mit Code außerhalb der Funktion zugegriffen werden kann. Dies bedeutet, dass die Funktion eine "Referenz" auf den Verschluss zurücksenden oder dieser "Referenz" einer externen Variablen zuweisen muss, um sicherzustellen, dass lokale Variablen im Verschluss durch externen Code zugegriffen werden. Natürlich sollte die Entität, die diese Referenz enthält, ein Objekt sein, da in JavaScript alle Reste mit Ausnahme der Grundtypen Objekte sind. Leider bietet ECMAScript keine relevanten Mitglieder und Methoden, um auf lokale Variablen in der Schließung zuzugreifen. In ECMAScript ist die im Funktionsobjekt definierte innere Funktion jedoch eine lokale Variable, die direkt auf externe Funktionen zugreifen kann. Durch diesen Mechanismus können wir auf folgende Weise den Zugang zum Verschluss vervollständigen.
Die Codekopie lautet wie folgt:
Funktionsgruß (Name) {
var text = 'Hallo' + Name; // Lokale Variable
// Jedes Mal, wenn ein Verschluss erzeugt wird und das interne Funktionsobjekt an den Anrufer zurückgegeben wird
return function () {alert (text); }
}
var Sayshello = Gruß ("Verschluss");
Sayshello () // Zugriff auf den lokalen variablen Text über den Verschluss zugreifen
Das Ausführungsergebnis des oben genannten Code ist: Hallo -Verschluss, da nach der Ausführung der Grußfunktion die Funktion Sayhello () weiterhin auf den darin definierten lokalen variablen Text zugreifen kann.
OK, dies ist die Wirkung des legendären Verschlusses. Verschlüsse haben viele Anwendungsszenarien und -modi in JavaScript, wie Singleton, Power Constructor und andere JavaScript -Modi, die mit der Verwendung von Schließungen untrennbar miteinander verbunden sind.
ECMascript -Verschlussmodell
Wie implementiert ECMascript Schließungen? Wenn Sie ein detailliertes Verständnis haben möchten, können Sie die ECMascript-Spezifikationen für die Forschung erhalten. Ich werde hier nur eine einfache Erklärung geben, und der Inhalt kommt auch aus dem Internet.
Wenn die Funktion des ECMascript -Skripts ausgeführt wird, hat jede Funktionsvereinigung ein Ausführungskontext -Szenario (Ausführungskontext), das drei Teile enthält.
Die Lexikalumgebung
Die Variableumgebung
Diese Bindung
Der dritte Punkt dieser Bindung hat nichts mit Schließungen zu tun und wird in diesem Artikel nicht erörtert. Eine in der grammatikalischen Umgebung verwendete variable Kennung zum Analysieren des Funktionsausführungsprozesses. Wir können uns eine grammatikalische Umgebung als ein Objekt vorstellen, das zwei wichtige Komponenten enthält: den Umgebungsaufzeichnung (Umweltrecodes) und eine externe Referenz (Zeiger). Der Umgebungsdatensatz enthält lokale Variablen und Parametervariablen, die intern von der Funktion deklariert wurden, und die externe Referenz zeigt auf das Kontextausführungsszenario des externen Funktionsobjekts. Dieser Referenzwert ist im globalen Kontextszenario null. Eine solche Datenstruktur bildet eine Einweg-verknüpfte Liste, wobei jeder Referenz auf das äußere Kontextszenario zeigt.
Zum Beispiel sollte das Verschlussmodell in unserem obigen Beispiel so sein. Die Sayhello -Funktion befindet sich auf der niedrigsten Ebene, die obere Ebene ist die Funktionsgruß, und die äußerste Ebene ist die globale Szene. Wie in der folgenden Abbildung gezeigt: Wenn Sayshello aufgerufen wird, wird Sayshello den Wert des lokalen variablen Textes in der Kontextszene findet, sodass die variable Umgebung "Hello Clospure" (die Variableumgebung) und die Grammatikumgebung im Grunde genommen gleich sind. Für bestimmte Unterschiede finden Sie im Dokument der ECMascript -Spezifikationsdokument.
Probenspalte von Schließungen
Im vorherigen Artikel verstehe ich grob, was der JavaScript -Verschluss ist und wie Schließungen in JavaScript implementiert werden. Im Folgenden werden wir Ihnen helfen, Schließungen tiefer zu verstehen, indem wir einige Beispiele abzielen. Nachfolgend finden Sie 5 Beispiele, und die Beispiele stammen aus JavaScript -Verschlüssen für Dummies (Spiegel). Beispiel 1: Lokale Variablen in Verschluss sind eher Referenzen als Kopien
Die Codekopie lautet wie folgt:
Funktion sagt667 () {
// Lokale Variable, die innerhalb des Verschlusses endet
var num = 666;
var sayAlert = function () {alert (num); }
num ++;
Return Sayalert;
}
var sayalert = say667 ();
SayArt ()
Daher sollte das Ausführungsergebnis 667 statt 666 auftauchen.
Beispiel 2: Mehrere Funktionen binden den gleichen Verschluss, da sie in derselben Funktion definiert sind.
Die Codekopie lautet wie folgt:
Funktion SetupsOMeGlobals () {
// Lokale Variable, die innerhalb des Verschlusses endet
var num = 666;
// Speichern Sie einige Verweise auf Funktionen als globale Variablen
galertNumber = function () {alert (num); }
ginCreaseNumber = function () {num ++; }
gsetNumber = function (x) {num = x; }
}
setupsomeglobals (); // Werte drei globale Variablen zuweisen
galertNumber (); // 666
ginCreaseNumber ();
galertNumber (); // 667
gsetNumber (12); //
galertNumber (); // 12
Beispiel 3: Bei der Zuweisung von Funktionen in einer Schleife binden diese Funktionen den gleichen Verschluss
Die Codekopie lautet wie folgt:
Funktion Buildlist (Liste) {
var result = [];
für (var i = 0; i <list.length; i ++) {
var item = 'item' + list [i];
result.push (function () {alert (item + '' + list [i])});
}
Rückgabeergebnis;
}
Funktion testlist () {
var fnlist = Buildlist ([1,2,3]);
// J nur zur Vorbeugung von Verwirrung - kann ich verwenden
für (var j = 0; j <fnlist.length; j ++) {
fnlist [j] ();
}
}
Das Ausführungsergebnis von Testlist ist, dass das undefinierte Fenster von Element3 dreimal auftaucht, da diese drei Funktionen den gleichen Verschluss binden und der Wert des Elements das letzte berechnete Ergebnis ist. Wenn ich jedoch aus der Loop herausspringt, ist der I -Wert 4, sodass das Ergebnis der Liste [4] undodiert ist.
Beispiel 4: Alle lokalen Variablen externer Funktionen befinden sich im Verschluss, auch wenn diese Variable nach der internen Funktionsdefinition deklariert wird.
Die Codekopie lautet wie folgt:
Funktion sageAlice () {
var sayAlert = function () {alert (Alice); }
// Lokale Variable, die innerhalb des Verschlusses endet
var alice = 'Hallo Alice';
Return Sayalert;
}
var helloalice = SayAlice ();
Helloalice ();
Das Ausführungsergebnis ist ein Fenster mit "Hello Alice" -Popup. Auch wenn die lokale Variable nach der Funktion der Funktion erscheint, kann auf die lokale Variable zugegriffen werden.
Beispiel 5: Erstellen Sie jedes Mal, wenn die Funktion aufgerufen wird
Die Codekopie lautet wie folgt:
Funktion NewClosure (Somenum, SomeRef) {
// Lokale Variablen, die innerhalb des Schließens enden
var num = Somenum;
var anarray = [1,2,3];
var ref = someref;
Rückgabefunktion (x) {
num += x;
Anarray.push (num);
alert ('num:' + num +
'/nanarray' + anarray.toString () + +
'/nref.somevar' + Ref.Somevar);
}
}
CloseRure1 = NewClosure (40, {selten: 'Closeur 1'});
CloseRure2 = NewClosure (1000, {selten: 'Closeur 2'});
Verschluss1 (5); // num: 45 anarray [1,2,3,45] ref: 'sonvar closure1' '
CloseRure2 (-10); // num: 990 Anarray [1,2,3,990] REF: 'SONDERVAR CLINTEURURE2' '
Anwendung von Schließungen
Singleton Single Piece:
Die Codekopie lautet wie folgt:
var Singleton = function () {
var privateVariable;
Funktion privatfunktion (x) {
... privatvariable ...
}
zurückkehren {
FirstMethod: Funktion (a, b) {
... privatvariable ...
},
Secondmethod: Funktion (c) {
... privateFunction () ...
}
};
} ();
Dieses einzelne Stück wird durch einen Verschluss erreicht. Die Einkapselung privater Mitglieder und Methoden wird durch Schließungen abgeschlossen. Die anonyme Hauptfunktion gibt ein Objekt zurück. Das Objekt enthält zwei Methoden, Methode 1 kann private Variablen verwenden, und Methode 2 kann auf interne private Funktionen zugreifen. Das, was zu beachten ist, ist das '()', bei dem die anonyme Hauptfunktion endet. Ohne dieses '()' kann ein einzelnes Stück nicht produziert werden. Weil anonyme Funktionen nur einzigartige Objekte zurückgeben können und nicht anderswo aufgerufen werden können. Dies ist die Methode, um Schließungen zur Erzeugung einzelner Stücke zu verwenden.