Im vorherigen Artikel gaben wir einen Überblick über die Voraussetzung. Bevor wir diesen Blog -Beitrag schreiben, wollten wir einige klassische Fälle schreiben. Wenn man bedenkt, dass diese Fälle umfassender sind, haben wir diesen Blog-Beitrag Schritt für Schritt, was einfacher zu erlernen ist und ein detailliertes JavaScript hat.
Sequenz
Ein Kollege ging zum Interview und der Interviewer stellte eine Frage: Schreiben Sie eine Schließung und ich werde sie lesen? Also schrieb mein Kollege schnell den folgenden Code:
Die Codekopie lautet wie folgt:
Funktion fn () {
Alert ('Hallo JavaScript -Verschluss !!!'); // Verdammt, E -Text ist nicht gut, du kannst die Schließwörter nur schreiben, nachdem du eine Übersetzung gefunden hast
}
fn ();
Dann schüttelte der Interviewer den Kopf und sagte: "Wie kann dies als Schließung bezeichnet werden?" Am Ende hatten die beiden einen Streit, und der Kollegen ging entschlossen. Was ist das Ding des Interviewers? (Diese Geschichte ist rein fiktiv, wenn es Ähnlichkeit gibt, ist sie rein Zufall)
Verschlüsse können in den Augen vieler Menschen "High-End und schwierige" Technologie sein, aber in den Augen vieler Menschen können sie als Schließungen angesehen werden:
Beispiel 1:
Die Codekopie lautet wie folgt:
Funktion fn () {
return function () {
alert ('Beispiel 1');
}
}
fn () ();
Beispiel 1 PS: Dieser sieht nicht sehr fortgeschritten aus, es scheint, dass diese Person nicht sehr gut darin ist!
Beispiel 2:
Die Codekopie lautet wie folgt:
; (function () {
alert ('Beispiel 2');
}) ();
Beispiel 2 PS: Dies sieht fortgeschrittener aus als der vorherige, und es gibt ein Semikolon vor der ersten Klammer. Warum ein Semikolon hinzufügen? Lassen Sie uns diese Frage zuerst hier lassen, und wir werden später darüber sprechen.
Beispiel 3:
Die Codekopie lautet wie folgt:
~ Funktion fn () {
alarm ('Beispiel 3')
} ();
Beispiel 3 PS: Dies ist am fortgeschrittensten, es ist so erstaunlich. Ich habe weniger gelesen, lüge mich nicht an!
Der Meister von Lun ist nicht sehr gut im Lesen und kann diese drei "Schließungen" nur schreiben. Ich glaube, dass Blogger mehr und bessere "Schließungen" schreiben können; Bitte halten Sie hier bitte zuerst meinen Unsinn und untersuchen Sie dann den Mechanismus des Funktionsbetriebs. Es scheint, dass jemand es bereits weiß, es muss der Umfang sein. Ich möchte diesen Titel wirklich nicht hinzufügen, also habe ich immer das Gefühl, dass es fast sinnvoll ist. Diese Dinge sind ursprünglich zusammen. Warum sollte ich sie also wiederholen? Alte Gewohnheit, laden Sie zuerst den Code hoch:
Die Codekopie lautet wie folgt:
var n = 10;
Funktion fn () {
Alarm (n);
var n = 9;
Alarm (n);
}
fn ();
Um es einfach auszudrücken, zeichnen wir Bilder (der Master verwendet nur die Zeichnungssoftware, die mit Windows geliefert wird. Wenn es bessere gibt, empfehlen Sie sie bitte den Bloggern), um sie zu analysieren:
Analyse 1
Aus der Abbildung sehen wir zwei Bereiche, einer ist das Fensterumfang (Umfang der oberen Ebene), und der andere ist ein privater Bereich, der gebildet wird, wenn FN aufgerufen wird. Was ist dann Umfang? Der Umfang ist tatsächlich die Umgebung für die Codeausführung. Zum Beispiel ist die Lernumgebung eines Schülers eine Schule, die seinem Geltungsbereich entspricht. Wenn der Schüler ungezogen ist und oft in Internet -Cafés geht, um nachts Spiele zu spielen, ist es gleichbedeutend mit der Bildung einer privaten Umgebung, der ein Internetcafé ist. In Ordnung! Diese Lizi ist so, bis sie aussieht wie die Meisterin selbst und sie kann nicht anders, als zu seufzen: "Wenn du nicht hart arbeitest, wenn du jung bist, wirst du getreten, wenn du erwachsen bist." Kehren wir zum Thema zurück. Tatsächlich bezieht sich die Definition der Funktion FN auf die Beschreibung eines Codestücks (der roten Box in der Abbildung). Wenn dieser FN aufgerufen wird (die grüne Box in der Abbildung), wird ein Zielfernrohr gebildet. Natürlich wird der Code in diesem Bereich vor der Ausführung ebenfalls ausbezogen. Ich werde Ihnen nicht sagen, dass dieser Bereich nach der Ausführung zerstört wird. Diese FN wird erneut aufgerufen und wird auch einen neuen Bereich bilden und dann vor der Ausführung vorbekundet, dann die Codehaltung und schließlich nach der Ausführung zerstört.
Schließungen verstehen
Wir wissen, dass ein privater Bereich (Ausführungsumgebung), wenn eine Funktion aufgerufen wird, einen privaten Bereich (Ausführungsumgebung) bildet und dieser private Bereich eine Schließung ist. Rückblickend ist die Schließung immer noch das legendäre "High-End und nicht einfach zu erreichen"? Lassen Sie uns auf die erste Interviewgeschichte zurückblicken, und die drei Beispiele, die ich geschrieben habe, sind sie tatsächlich Schließungen. Um genau zu sein, sind diese drei Beispiele häufige Formen von Schließungen.
Anwendungsszenarien
Jetzt gibt es eine Anforderung: Auf der HTML -Seite gibt es ein UL -Tag, und es gibt 5 Li -Tags unter UL. Sie benötigen einen Klick auf ein LI, und der Index (Index startet ab 0), in dem das klickte Li aufgetaucht ist. Die HTML -Struktur lautet wie folgt:
Die Codekopie lautet wie folgt:
<ul id = "ul">
<li> Liste 1 </li>
<li> Liste 2 </li>
<li> Liste 3 </li>
<li> Liste 4 </li>
<li> Liste 5 </li>
</ul>
Ich war klug und schrieb schnell den folgenden Code:
Die Codekopie lautet wie folgt:
var lis = document.getElementById ('ul').
für (var i = 0, len = lis.length; i <len; i ++) {
lis [i] .onclick = function () {
Alarm (i);
};
}
Abschließender Test, um festzustellen, ob diese Anforderung perfekt implementiert ist:
Ich fand heraus, dass dieses Ergebnis egal wie oft ich geklickt habe, und das gewünschte Ergebnis ist: Klicken Sie auf Liste 1, um aufliste zu klicken, um aufliste zu kommen, um aufliste zu kommen, und klicken Sie auf Liste 3, um 2 zu geben. In diesem Moment möchte ich dieses Bild nur verwenden, um meine aktuelle Stimmung zu beschreiben:
(Wie sieht es aus, wenn der Prototyp während der Demonstration nicht als Entwurfsanforderungen ausgeführt wird)
Was soll ich tun? Warum taucht 5 immer auf? In der Theorie ist es sehr richtig! Zeichnen wir ein Bild, um zu analysieren:
Tatsächlich geben wir nur jedem Li -Onclick, was eigentlich eine Funktionsbeschreibungszeichenfolge ist, die speichert. Der Inhalt dieser Zeichenfolge ist der Inhalt im roten Feld des obigen Bildes. Wenn Sie es immer noch nicht glauben, habe ich das Bild und die Wahrheit:
Geben Sie: LIS [4]. Wenn wir auf die 5. Liste klicken, entspricht sie tatsächlich LIS [4] .onclick (). Nachdem wir diese Funktionsbeschreibung aufgerufen haben, wissen wir, dass die Funktion, wenn sie ausgeführt wird, einen privaten Bereich bildet. In diesem privaten Bereich wird es zuerst vorbekommen und dann wird der Code ausgeführt. Zu diesem Zeitpunkt werden wir nach mir suchen. Es gibt kein I unter dem aktuellen privaten Bereich und finde dann ich unter dem Fensterbereich, also taucht jedes Mal auf, wenn wir klicken.
Offensichtlich kann der obige Code diese Anforderung nicht erfüllen. Es ist falsch, unseren Code zu schreiben. Denken wir über die Gründe für das Problem nach? Der Grund dafür ist, dass jedes Mal, wenn ich klicke, es im I unter Fenster gelesen wird. Zu diesem Zeitpunkt ist der Wert dieses I -Werts bereits 5, sodass der folgende Code verfügbar ist:
Methode 1:
Die Codekopie lautet wie folgt:
var lis = document.getElementById ('ul').
Funktion fn (i) {
return function () {
Alarm (i);
}
}
für (var i = 0, len = lis.length; i <len; i ++) {
lis [i] .onclick = fn (i);
}
Methode 2:
Die Codekopie lautet wie folgt:
var lis = document.getElementById ('ul').
für (var i = 0, len = lis.length; i <len; i ++) {
; (Funktion (i) {
lis [i] .onclick = function () {
Alarm (i);
};
})(ich);
}
Methode 3:
Die Codekopie lautet wie folgt:
var lis = document.getElementById ('ul').
für (var i = 0, len = lis.length; i <len; i ++) {
lis [i] .onclick = Funktion fn (i) {
return function () {
Alarm (i);
}
}(ich);
}
Ich habe drei Methoden in einem Atemzug geschrieben, und die Ideen sind die gleichen, nämlich diese Variable I in einer privaten Variablen zu speichern. Hier werde ich nur über Methode zwei sprechen. Wenn Sie einen von ihnen verstehen, werden Sie natürlich den Rest verstehen. Laut Konvention zeichnen wir ein Bild und analysieren Sie es Schritt für Schritt:
Ich habe die gesamte Codeausführung im Detail beschrieben. Es ist zu beachten, dass das Onclick -Attribut jedes Li den (i) (i) {…}) (i) Umfang besetzen muss. Wenn diese Funktion ausgeführt wird, wird sie nicht zerstört, da sie vom äußeren Li besetzt ist (dieses Li ist unter dem Fensterbereich), sodass dieses Zielfernrohr nicht zerstört wird. Beim Klicken auf eine Li, function () {alert (i); } wird ausgeführt und ein Umfang bildet sich ebenfalls. Dieser Bereich hat ich nicht. Es wird zu (function () {…}) (i) Umfang, um i zu finden, und schließlich I im formalen Parameter zu finden, und der Wert dieses formalen Parameters wird während der für Schleife übergeben; In diesem Beispiel werden Schließungen geschickt verwendet, um den Wert zu speichern und das Problem perfekt zu lösen.
PS: Ich habe gerade gesagt (Funktion (i) {…}) (i) Warum ich ein Semikolon davor hinzugefügt habe, soll verhindern, dass die vorherige Aussage vergessen, ein Semikolon hinzuzufügen, was dazu führt, dass JavaScript während der Parsen Fehler machte, und das ist alles. Natürlich ist eines der oben genannten Anwendungsszenarien das Prinzip der Registerkarten implementiert. Es kann andere Implementierungsmethoden geben, z. B. benutzerdefinierte Attributmethoden und das Finden von Indizes über DOM -Knotenbeziehungen. Der Meister übernimmt diese Methode nur, um sein Verständnis von Schließungen zu vertiefen.
Zusammenfassen
Schließungen sind nicht so groß wie die legendären. Der Kern besteht darin, Funktionsdefinitionen und -aufrufe zu verstehen. Ein neuer privater Bereich wird gebildet, wenn eine Funktion aufgerufen wird. Wenn ein Zielfernrohr von außen besetzt ist, wird das Zielfernrohr nicht zerstört. Der Meister von Lu liest sehr wenig. Wenn es falsche Dinge gibt, korrigieren Sie mich bitte durch Blogger. Gleichzeitig möchte ich Ihnen für Ihre Unterstützung für den Artikel von Lukes von Lukas danken.