1. Was ist ein Abschluss?
Ein Abschluss ist eine Funktion, die Zugriff auf eine Variable im Gültigkeitsbereich einer anderen Funktion hat.
Einfach ausgedrückt ermöglicht Javascript die Verwendung interner Funktionen – das heißt, Funktionsdefinitionen und Funktionsausdrücke befinden sich im Funktionskörper einer anderen Funktion. Darüber hinaus haben diese inneren Funktionen Zugriff auf alle lokalen Variablen, Parameter und anderen inneren Funktionen, die in der äußeren Funktion deklariert sind, in der sie existieren. Ein Abschluss wird gebildet, wenn eine dieser inneren Funktionen außerhalb der äußeren Funktion aufgerufen wird, die sie enthält.
2. Umfang der Variablen
Um Abschlüsse zu verstehen, müssen Sie zunächst den Umfang der Variablen verstehen.
Der Umfang von Variablen besteht lediglich aus zwei Typen: globale Variablen und lokale Variablen.
Das Besondere an der Javascript-Sprache ist, dass globale Variablen direkt innerhalb der Funktion gelesen werden können.
Die interne Funktion kann auf die Variablen der externen Funktion zugreifen, da die Bereichskette der internen Funktion den Bereich der externen Funktion umfasst.
kann auch verstanden werden als: der Bereich der internen Funktion Funktion Strahlung erreicht den Umfang der externen Funktion;
var n=999; function f1(){ alert(n); } f1(); // 999
Andererseits können die lokalen Variablen innerhalb der Funktion nicht außerhalb der Funktion gelesen werden.
function f1(){ var n=999; } alert(n); // error
Hier gibt es etwas zu beachten: Wenn Sie Variablen innerhalb einer Funktion deklarieren, müssen Sie den Befehl var verwenden. Wenn Sie es nicht verwenden, deklarieren Sie tatsächlich eine globale Variable!
function f1(){ n=999; } f1(); alert(n); // 999
Mehrere Möglichkeiten, Abschlüsse zu schreiben und zu verwenden
3.1. Fügen Sie der Funktion einige Attribute hinzu
function Circle(r) { this.r = r; } Circle.PI = 3.14159; Circle.prototype.area = function() { return Circle.PI * this.r * this.r; } var c = new Circle(1.0); alert(c.area()); //3.14159
3.2 werden Variablen als Werte zugewiesen
var Circle = function() { var obj = new Object(); obj.PI = 3.14159; obj.area = function( r ) { return this.PI * r * r; } return obj; } var c = new Circle(); alert( c.area( 1.0 ) ); //3.14159
3.3 Diese Methode wird häufig verwendet und ist die bequemste. var obj = {} besteht darin, ein leeres Objekt zu deklarieren
var Circle={ "PI":3.14159, "area":function(r){ return this.PI * r * r; } }; alert( Circle.area(1.0) );//3.14159
4. Die Hauptfunktion des Verschlusses
Der Verschluss kann an vielen Stellen verwendet werden. Seine größten Verwendungszwecke sind zwei: Einer besteht darin, die Variablen innerhalb der Funktion zu lesen, wie bereits erwähnt, und der andere darin, die Werte dieser Variablen im Speicher zu halten.
4.1. Wie liest man lokale Variablen von außen?
Aus verschiedenen Gründen müssen wir manchmal lokale Variablen innerhalb einer Funktion abrufen. Dies ist jedoch, wie bereits erwähnt, im Normalfall nicht möglich und kann nur durch Workarounds erreicht werden.
Das heißt, eine Funktion innerhalb der Funktion zu definieren.
function f1(){ var n=999; function f2(){ alert(n); // 999 } }
Im obigen Code ist die Funktion f2 in der Funktion f1 enthalten. Zu diesem Zeitpunkt sind alle lokalen Variablen in f1 für f2 sichtbar. Aber das Gegenteil funktioniert nicht. Die lokalen Variablen in f2 sind für f1 unsichtbar. Dies ist die für die Javascript-Sprache einzigartige „Kettenbereichsstruktur“. Das untergeordnete Objekt sucht Ebene für Ebene nach den Variablen aller übergeordneten Objekte. Daher sind alle Variablen des übergeordneten Objekts für das untergeordnete Objekt sichtbar, umgekehrt jedoch nicht.
Da f2 die lokalen Variablen in f1 lesen kann, können wir dann nicht seine internen Variablen außerhalb von f1 lesen, solange f2 als Rückgabewert verwendet wird?
function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
4.2. Wie behält man den Wert einer Variablen im Speicher?
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
In diesem Code ist das Ergebnis tatsächlich die Abschlussfunktion f2. Es wurde zweimal ausgeführt, beim ersten Mal war der Wert 999, beim zweiten Mal war der Wert 1000. Dies beweist, dass die lokale Variable n in der Funktion f1 immer im Speicher gespeichert ist und nach dem Aufruf von f1 nicht automatisch gelöscht wird.
Warum passiert das? Der Grund dafür ist, dass f1 die übergeordnete Funktion von f2 ist und f2 einer globalen Variablen zugewiesen ist, wodurch f2 immer im Speicher bleibt und die Existenz von f2 von f1 abhängt, sodass f1 immer im Speicher ist und nicht gelöscht wird Nach Abschluss des Anrufs wird es vom Garbage-Collection-Mechanismus recycelt.
Eine weitere erwähnenswerte Sache in diesem Code ist die Zeile „nAdd=function(){n+=1}“. Erstens wird das Schlüsselwort var nicht vor nAdd verwendet, daher ist nAdd eher eine globale Variable als lokale Variablen. Zweitens ist der Wert von nAdd eine anonyme Funktion, und diese anonyme Funktion selbst ist auch ein Abschluss, sodass nAdd einem Setter entspricht, der lokale Variablen innerhalb der Funktion außerhalb der Funktion bearbeiten kann.
5. Abschluss und dieses Objekt
Die Verwendung dieses Objekts in einem Abschluss kann zu Problemen führen. Da die Ausführung anonymer Funktionen global ist, zeigt dieses Objekt normalerweise auf das Fenster. Der Code lautet wie folgt:
var name = "The window"; var object = { name:"My object", getNameFun:function(){ return function(){ return this.name; }; } }; alert(object.getNameFun(){}); //"The window"(在非严格模式下)
Speichern Sie dieses Objekt im externen Bereich in einem Abschluss Für den Zugriff auf Variablen kann der Abschluss verwendet werden, um auf das Objekt zuzugreifen. Der Code lautet wie folgt:
var name = "The window"; var object = { name:"My object", getNameFun:function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFun(){}); //“My object”
6. Abschlüsse und Speicherlecks
Insbesondere wenn ein HTML-Element im Bereich des Abschlusses gespeichert ist, bedeutet dies, dass das Element nicht zerstört werden kann . Wie folgt:
function assignHandler(){ var element = document.getElementById("someElement"); element.onclick = function(){ alert(element.id); } }
Der obige Code erstellt einen Abschluss als Element-Ereignishandler, und dieser Abschluss erstellt einen Zirkelverweis. Da die anonyme Funktion einen Verweis auf das aktive Objekt von „assignHandler()“ speichert, kann die Anzahl der Verweise auf das Element nicht reduziert werden. Solange die anonyme Funktion existiert, beträgt die Referenznummer des Elements mindestens 1, sodass der von ihr belegte Speicher nicht wiederverwendet wird.
Lösen Sie das Problem der internen Nicht-Recyclingfähigkeit, indem Sie den Code neu schreiben:
function assignHandler(){ var element = document.getElementById("someElement"); var id = element.id; element.onclick = function(){ alert(id); } element = null; }
Der obige Code erkennt, dass der Abschluss nicht direkt auf das Element verweist und dennoch eine Referenz gespeichert wird das aktive Objekt, das die Funktion enthält. Daher ist es notwendig, die Elementvariable auf Null zu setzen, damit der von ihr belegte Speicher normal recycelt werden kann.
7. Zu beachtende Punkte bei der Verwendung von Verschlüssen
1) Da Schließungen dazu führen, dass die Variablen in der Funktion im Speicher gespeichert werden, was viel Speicher verbraucht, können Schließungen nicht missbraucht werden, da es sonst zu Leistungsproblemen auf der Webseite und möglicherweise zu Speicherverlusten im IE kommt . Die Lösung besteht darin, alle nicht verwendeten lokalen Variablen zu löschen, bevor die Funktion beendet wird.
2) Der Abschluss ändert den Wert der Variablen innerhalb der übergeordneten Funktion außerhalb der übergeordneten Funktion. Wenn Sie daher die übergeordnete Funktion als Objekt, den Abschluss als öffentliche Methode und die internen Variablen als privaten Wert verwenden, müssen Sie darauf achten, den Wert der Variablen innerhalb der übergeordneten Funktion nicht zu ändern.
Das Obige ist eine detaillierte Erklärung der Schreibweise und Funktion von Abschlüssen, die der Herausgeber eingeführt hat. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht Ich werde Ihnen rechtzeitig antworten. Ich möchte mich auch bei Ihnen allen für Ihre Unterstützung der chinesischen PHP-Website bedanken!
Ausführlichere Erläuterungen zum Schreiben und zur Funktion von Abschlüssen in JavaScript finden Sie auf der chinesischen PHP-Website!