Im Prozess des Front-End-Lernens werden wir unweigerlich auf viele Probleme stoßen. Deshalb werden wir heute aus der Sicht eines Anfängers über zwei Fragen sprechen:
Was ist ein Abschluss?
Welche Funktionen haben Verschlüsse?
Tatsächlich gibt es beim Erlernen von JavaScript überall Abschlüsse, man muss sie nur erkennen und akzeptieren können. Abschlüsse sind kein Werkzeug, für dessen Verwendung das Erlernen einer neuen Syntax oder eines neuen Musters erforderlich ist. Abschlüsse sind eine natürliche Folge des Schreibens von Code, der auf dem lexikalischen Bereich basiert. Beim Schreiben von Code müssen wir selten absichtlich Abschlüsse erstellen.
Ich glaube, dass viele Freunde zu diesem Zeitpunkt bereits in ihrem Herzen murmeln: Was ist dieser lexikalische Umfang? Keine Panik, hören Sie mir einfach langsam zu. Kurz gesagt, der lexikalische Umfang ist der Umfang, der in der lexikalischen Phase definiert wird. Mit anderen Worten: Der lexikalische Bereich wird dadurch bestimmt, wo Sie Variablen und Bereiche auf Blockebene platzieren, wenn Sie Ihren Code schreiben, sodass der Bereich unverändert bleibt, wenn der lexikalische Analysator den Code verarbeitet (meistens). ——„JavaScript, das Sie nicht kennen“
Nehmen wir zunächst ein Beispiel:
function test(){ var arr = [] for(var i=0;i<10;i++){ arr[i]=function(){ console.log(i); } } Rückkehr ank } var myArr = test() // myArr[0]() // myArr[1]() // ... for(var j = 0; j < 10; j++){ myArr[j]() } // Um Langeweile zu vermeiden, wird hier eine zweite Schleife verwendet, um die Funktion in der ersten Schleife in der Testfunktion aufzurufen und zehn Ergebnisse auszudrucken
: Wenn dieser Code ausgeführt wird, wird er nach gesundem Menschenverstand ausgeführt sollte analysiert werden. Es gibt zehn Zahlen von 0 bis 9 nacheinander aus, aber die for-Schleife benötigt keine Zeit zum Ausführen (vernachlässigt in Mikrosekunden). Wenn der Funktionstest arr zurückgibt, gibt es 10 function(){console );}, die Funktion im Array wird zu diesem Zeitpunkt nicht ausgeführt, wenn var myArr = test() die Testfunktion aufruft, da die Ausführungszeit der for-Schleife ignoriert wird, ist i zu diesem Zeitpunkt bereits 10, also was ist gedruckt ist 10 von 10.
Ich glaube, jetzt wird jemand fragen: Was hat das mit der Schließung zu tun, über die wir sprechen werden? Wenn wir diesen Code also leicht modifizieren und ihn in einen Akkumulator umwandeln, wie können wir ihn dann implementieren?
Ich glaube, dass es zu diesem Zeitpunkt große Köpfe geben wird. Wer kann sagen, ist das nicht einfach?
Ändern Sie die var-Definition in eine let-Definition, sodass die erste for-Schleife zu einem Gültigkeitsbereich auf Blockebene wird und dann zu einem Akkumulator werden kann. Natürlich gibt es kein Problem,
aber wir sprechen heute darüber, wie man einen Akkumulator in ES5 implementiert. Dann schauen wir uns den folgenden Code an:
function test(){ var arr = [] for(var i=0;i<10;i++){ (Funktion(j){ arr[j]=function(){ console.log(j); } })(ich) } Rückkehr ank } var myArr = test() for(var j = 0; j < 10; j++){ myArr[j]() }
Aufmerksame Freunde werden definitiv feststellen, dass dies darin besteht, den Funktionskörper in der Schleife in eine selbstausführende Funktion zu ändern, aber das Ausgabeergebnis besteht zu diesem Zeitpunkt darin, zehn Zahlen von 0 bis 9 nacheinander auszugeben, einschließlich des Abschlusspakets. Wenn wir mit der Ausführung dieses Codes beginnen, wird die zweite for-Schleife zehnmal aufgerufen. Wenn jede selbstausführende Funktion ausgeführt wird, wird ein AO-Objekt der selbstausführenden Funktion erstellt . Der Attributname ist j. Normalerweise sollte das AO-Objekt von arr[j] nach der Ausführung der Funktion zerstört werden Ich habe jetzt nach dem Attributnamen j gesucht, ihn aber nicht gefunden. Ich habe ihn im AO-Objekt der selbstausführenden Funktion gefunden. Wenn die selbstausführende Funktion endet, ist sie AO Das Objekt wird vom Garbage-Collection-Mechanismus nicht recycelt, andernfalls wird bei der Ausführung von myarr[j] () ein Fehler gemeldet und ein Abschluss gebildet.
Nehmen wir eine weitere Beispielfunktion
a(){. Funktion b(){ var bbb = 234 console.log(aaa); } var aaa = 123 return b // b wurde in a geboren, aber gerettet} varglob = 100 var demo = a()Wir verwenden zunächst die Vorkompilierung, um den Code von
demo()zu analysieren
. Suchen Sie zunächst nach der globalen Variablendeklaration, die als Attributname von GO verwendet wird ist undefiniert. Bei der Funktionsdeklaration wird der Funktionsname als Attributname des GO-Objekts verwendet und der Wert wird dem Funktionskörper zugewiesen. Zu diesem Zeitpunkt sollte es GO{ glob: undefiniert--->100; demo: a: fa(){} } sein. Dann erstellen Sie ein AO{ aaa: undefiniert--->123;b: fb() für Funktion a {} } und schließlich Funktion b in Funktion a vorkompilieren, um ein AO von b { b: undefiniert ---> 234} zu erstellen. Zu diesem Zeitpunkt ist die Reihenfolge der Bereichskette 1. AO-Objekt der Funktion b; 2. AO-Objekt der Funktion a; 3. Globales GO-Objekt. Wenn wir aaa in Funktion b ausgeben, beginnen wir am Anfang der Bereichskette. Wenn im AO-Objekt der Funktion b kein aaa vorhanden ist, suchen wir entlang der Bereichskette nach unten, um den AO der Funktion a der zweiten Ebene zu finden Das Ziel besteht darin, den Wert von aaa als 123 zu ermitteln und das Ergebnis auszugeben.
Wenn wir es nicht aus der Perspektive der Vorkompilierung analysieren würden, würden wir denken, dass aaa zu diesem Zeitpunkt einen Fehler melden sollte. Wenn var demo = a() ausgeführt wird und die Ausführung der a-Funktion endet, dann das entsprechende AO-Objekt a sollte laut Common Sense-Analyse zerstört werden: Wenn wir die Demo ausführen, sollte die Scope-Kette das AO-Objekt und das GO-Objekt von b erstellen. Der Wert von aaa sollte nicht ausgedruckt werden, aber zu diesem Zeitpunkt ist der Wert von aaa Der Wert ist 123, was bedeutet, dass das AO-Objekt von a nicht zerstört wurde. Warum also? Der Grund dafür ist, dass hier ein Abschluss erstellt wird. Wenn die Ausführung von var demo = a () abgeschlossen ist, fragt der Garbage Collection-Mechanismus: „Bruder, ich glaube, Sie haben die Ausführung abgeschlossen.“ Kann Ihr laufender Speicher für mich freigegeben werden? ? , aber zu diesem Zeitpunkt konnte Funktion a nur hilflos den Kopf schütteln und sagte: „Bruder, ich bin mir nicht sicher, ob ich die Ausführung abgeschlossen habe. Ich habe a b erstellt, aber b steht nicht unter meiner Kontrolle, also bin ich es.“ Ich bin mir nicht sicher, ob b. aufgerufen wurde, daher bin ich mir nicht sicher, ob ich die Ausführung abgeschlossen habe. Da Sie es nicht wissen, werde ich es nicht recyceln. Ich sollte einen Fehler melden, also zu diesem Zeitpunkt ein Das AO-Objekt wird nicht recycelt.
Ich glaube, dass Sie durch diese beiden Beispiele bereits ein allgemeines Verständnis von Abschlüssen haben. Lassen Sie uns als Nächstes über die Funktionen von Abschlüssen sprechen.
Die Funktiondes
Abschlusses besteht darin,
- öffentliche Variablen zu implementieren. Beispielsweise kann der Akkumulator (3.js)
- zwischengespeichert werden,
- um eine Kapselung, Privatisierung
- und modulare Entwicklung von Attributen zu erreichen und eine Kontamination globaler Variablen zu verhindern.
3.js).
Var-Anzahl = 0 Funktion add() { Gibt count++ zurück } console.log(add()); console.log(add()); console.log(add());
Dies ist ein relativ häufiger Akkumulationscode, aber wenn das Unternehmen während unseres Praktikums oder sogar bei der Arbeit verlangt, dass Sie den Akkumulator in einen modularen Code kapseln, dann aus Gründen der Modul Wir versuchen, die Definition globaler Variablen so weit wie möglich zu vermeiden, aber wie können wir dies erreichen, ohne globale Variablen zu definieren? Zu diesem Zeitpunkt können wir Abschlüsse verwenden.
Funktion add() { Var-Anzahl = 0 Funktion a() { ++zählen console.log(count); } zurückgeben a } var res = add() res() res() // Nach Beendigung der Add-Funktion wird das AO-Objekt von Add nicht zerstört, da nach Ausführung der Add-Funktion das zurückgegebene a einen Abschluss bildet, ohne zu wissen, ob es aufgerufen wurde, sodass es ohne Verwendung in ein Modul gekapselt werden kann Globale Variablen.
: Dies sind einige meiner persönlichen Meinungen zu Verschlüssen und ihren Funktionen. Nach dem anschließenden Studium und der Verbesserung wird es weitere Artikel geben. Vielen Dank fürs Zuschauen korrigieren und gemeinsam Fortschritte machen.