Einführungveranschaulichen Dieser Artikel stellt die Rolle, den Zweck und das Prinzip von JavaScript-Closures vor. Definition von „Closure“ Abschluss bedeutet, dass die innere Funktion immer auf die in der äußeren Funktion deklarierten Variablen und Parameter zugreifen kann, auch in der äußeren Funktion. Nach Rückgabe der Nummer (Lebensdauer abgelaufen). Die Rolle (Eigenschaften) von Verschlüssen 1. Funktionen innerhalb von Funktionen 2. Interne Funktionen können auf Parameter oder Variablen externer Funktionen verweisen 3. Für die Parameter und Variablen der externen Funktion erfolgt keine Speicherbereinigung, da sie von der internen Funktion referenziert werden. Closures und globale Variablen Verwendung von VerschlüssenCurryenÜber Parameter können verschiedene Funktionen generiert werden. Funktion makeWelcome(x) { Rückgabefunktion (y) { gib x + y zurück; }; } sagen wir „Hallo“ = „Willkommen heißen“ („Hallo,“); sagen wir „Hi“ = „Welcome("Hi,"); console.log(sagHallo("Tony")); console.log(sagHallo("Tony")); Ergebnis
Implementieren öffentlicher VariablenAnforderung: Implementieren Sie einen Akkumulator, der sich bei jedem Aufruf um eins erhöht. Funktion makeCounter(){ lass count = 0; Funktion innereFunktion(){ Anzahl zurückgeben++; } innere Funktion zurückgeben; } Lassen Sie Zähler = makeCounter(); console.log(Zähler()); console.log(Zähler()); console.log(Zähler()); Ergebnis
CacheStellen Sie sich vor, es gibt ein Funktionsobjekt, dessen Verarbeitung sehr zeitaufwändig ist. Der berechnete Wert kann gespeichert werden. Wenn diese Funktion aufgerufen wird, wird zuerst im Cache danach gesucht. Wird dieser nicht gefunden, wird er berechnet, anschließend der Cache aktualisiert und der Wert zurückgegeben, wird er gefunden, wird der gefundene Wert direkt zurückgegeben. Dies ist bei Closures möglich, da sie keine externen Referenzen freigeben und der Wert innerhalb der Funktion somit erhalten bleibt. Der Einfachheit halber wird in diesem Artikel direkt ein Beispiel für einen Lese-/Schreib-Cache beschrieben. (Anstatt es zu berechnen, wenn es nicht gelesen werden kann, und es dann im Cache zu speichern). let cache = funktion () { // Map erlaubt Schlüssel jeden Typs. Wenn Sie schreiben: let storage = {}, kann der Schlüssel nur eine Zeichenfolge sein: let storage = new Map(); zurückkehren { setCache: Funktion (k, v) { Speicher[k] = v; }, getCache: Funktion (k) { Rückgabespeicher[k]; }, deleteCache: Funktion (k) { Speicher löschen[k]; } } }(); cache.setCache('a', 1); Konsole.log(Cache.getCache('a')) Ergebnis
Kapselung (Privatisierung von Attributen)Auf interne Variablen kann nur über den bereitgestellten Abschluss zugegriffen werden. (Diese Methode ist nicht gut, es wird empfohlen, die Prototypkette zu verwenden). lass Person = Funktion(){ //Der Variablenbereich liegt innerhalb der Funktion und kann von außen nicht aufgerufen werden let name = "defaultName"; zurückkehren { getName: Funktion(){ Rückgabename; }, setName: Funktion(neuerName){ Name = neuerName; } } }(); Konsole.log(Person.Name); console.log(person.getName()); person.setName("Hallo"); console.log(person.getName()); Ergebnis
Das Prinzip der SchließungNehmen wir den Zähler als Beispiel: Funktion makeCounter() { lass count = 0; return Funktion() { Anzahl zurückgeben++; }; } lass Zähler = makeCounter(); console.log(Zähler()); console.log(Zähler()); console.log(Zähler()); Ergebnis
Zu Beginn jedes makeCounter()-Aufrufs wird ein neues LexicalEnvironment-Objekt erstellt, um die Variablen für diese makeCounter-Laufzeit zu speichern. Daher gibt es zwei Ebenen verschachtelter lexikalischer Umgebungen: Die Ausführung von makeCounter() erstellt eine verschachtelte Funktion, die nur eine Zeile einnimmt: return count++ . Wir haben es noch nicht ausgeführt, wir haben es nur erstellt. Alle Funktionen merken sich die lexikalische Umgebung, in der sie bei ihrer „Geburt“ erstellt wurden. Begründung: Alle Funktionen haben ein verstecktes Attribut namens [[Umgebung]], das einen Verweis auf die lexikalische Umgebung enthält, in der die Funktion erstellt wurde: Daher verfügt counter.[[Environment]] über einen Verweis auf die lexikalische Umgebung {count: 0}. Auf diese Weise merkt sich eine Funktion, wo sie erstellt wurde, unabhängig davon, wo die Funktion aufgerufen wird. Die [[Umgebung]]-Referenz wird beim Erstellen der Funktion festgelegt und dauerhaft gespeichert. Später, wenn counter() aufgerufen wird, wird für diesen Aufruf eine neue lexikalische Umgebung erstellt und deren äußere Referenz auf die lexikalische Umgebung wird von counter.[[Umgebung]] abgerufen : Wenn der Code in counter() nun nach der Zählvariable sucht, durchsucht er zuerst seine eigene lexikalische Umgebung (die leer ist, da dort keine lokalen Variablen vorhanden sind), dann die lexikalische Umgebung des äußeren makeCounter() und fixiert die Zählvariable, wo immer er sie findet. Ändern (aktualisieren Sie die Variable in der lexikalischen Umgebung, in der die Variable vorhanden ist). Dies ist der Status nach der Ausführung: Wenn wir counter() mehrmals aufrufen, erhöht sich die Zählvariable an derselben Position auf 2, 3 usw. SpeicherbereinigungEinführungNormalerweise werden nach Abschluss eines Funktionsaufrufs die lexikalische Umgebung und alle darin enthaltenen Variablen aus dem Speicher gelöscht, da keine Verweise mehr darauf vorhanden sind. Wie jedes andere Objekt in JavaScript bleibt eine lexikalische Umgebung nur so lange im Speicher, wie sie erreichbar ist. Wenn es jedoch eine verschachtelte Funktion gibt, die auch nach Beendigung der Funktion noch erreichbar ist, verfügt sie über ein [[Umgebung]]-Attribut, das auf die lexikalische Umgebung verweist. Wenn die lexikalische Umgebung nach Abschluss der Funktion noch erreichbar ist, bleibt die verschachtelte Funktion wirksam. Zum Beispiel: Funktion f() { sei Wert = 123; return Funktion() { Alarm(Wert); } } // g.[[Environment]] speichert einen Verweis auf die lexikalische Umgebung des entsprechenden f()-Aufrufs let g = f(); Wenn f() mehrmals aufgerufen wird und die zurückgegebene Funktion gespeichert wird, bleiben auch alle entsprechenden LexicalEnvironment-Objekte im Speicher erhalten. Zum Beispiel: Funktion f() { lass Wert = Math.random(); Rückgabefunktion () { Alarm(Wert); }; } // 3 Funktionen in einem Array, jede mit der lexikalischen Umgebung des entsprechenden f() verknüpft. let arr = [f(), f(), f()]; Wenn ein LexicalEnvironment-Objekt nicht mehr erreichbar ist, stirbt es (wie jedes andere Objekt auch). Mit anderen Worten: Es existiert nur, solange mindestens eine verschachtelte Funktion darauf verweist. Wenn im folgenden Code die verschachtelte Funktion gelöscht wird, wird auch die sie umgebende lexikalische Umgebung (und der darin enthaltene Wert) aus dem Speicher gelöscht: Funktion f() { sei Wert = 123; return Funktion() { Alarm(Wert); } } let g = f(); // Solange die g-Funktion existiert, bleibt der Wert im Speicher g = null; // Jetzt wird der Speicher bereinigt Optimierung in der Ist-EntwicklungWie wir gesehen haben, existieren theoretisch auch alle Variablen außerhalb einer Funktion, wenn diese erreichbar ist. Aber in Wirklichkeit versuchen JavaScript-Engines, es zu optimieren. Sie analysieren die Variablenverwendung und wenn aus dem Code klar hervorgeht, dass unbenutzte externe Variablen vorhanden sind, werden diese entfernt. Ein wichtiger Nebeneffekt hiervon in V8 (Chrome, Opera) ist, dass solche Variablen beim Debuggen nicht verfügbar sind. Öffnen Sie die Entwicklertools des Chrome-Browsers und versuchen Sie, den folgenden Code auszuführen. Funktion f() { lass Wert = Math.random(); Funktion g() { Debugger; } g zurückgeben; } sei g = f(); G(); Wenn der Code bis zur Stelle „debugger;“ ausgeführt wird, wird er angehalten. Geben Sie zu diesem Zeitpunkt console.log(value); in die Konsole ein. Ergebnis: Fehler: VM146:1 Uncaught ReferenceError: Wert ist nicht definiert Dies kann zu interessanten Debugging-Problemen führen. Beispielsweise können wir anstelle der erwarteten Variable eine externe Variable mit demselben Namen sehen: let value = "Überraschung!"; Funktion f() { let value = "der nächste Wert"; Funktion g() { Debugger; } g zurückgeben; } sei g = f(); G(); Wenn der Code bis zur Stelle „debugger;“ ausgeführt wird, wird er angehalten. Geben Sie zu diesem Zeitpunkt console.log(value); in die Konsole ein. Ergebnis: Ausgabe: Überraschung. Oben finden Sie ausführliche Informationen zum Prinzip und zur Funktion des JavaScript-Closures. Weitere Informationen zum JavaScript-Closure finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Vier völlig unterschiedliche Erfahrungen im Interaktionsdesign der Apple Watch enthüllt
>>: Detaillierte Erklärung des Integer-Datentyps tinyint in MySQL
Die dekomprimierte Version von MySQL ist installi...
ChunkFive Freie Schriftfamilie Cuprum JAH I Kosten...
In den vorherigen Kapiteln haben wir die Auswahl ...
1. css: dragTable.css @Zeichensatz "UTF-8&qu...
VMware vSphere ist die branchenführende und zuver...
Inhaltsverzeichnis 1. Verwenden Sie den Befehl „r...
Inhaltsverzeichnis So starten Sie mysqld Methode ...
Modulares Cocos Creator-Skript Mit Cocos Creator ...
OBS studio ist cool, aber JavaScript ist cooler. ...
1. Laden Sie das Installationspaket mysql-5.7.17-...
Beim Erstellen einer Website habe ich festgestellt...
Softwareversion Windows: Windows 10 MySQL: mysql-...
In diesem Artikelbeispiel wird der spezifische Co...
Laden Sie das Redis-Image herunter Docker-Pull yy...
Inhaltsverzeichnis 1. Einleitung 2. Erstellen Sie...