Heim >Web-Frontend >js-Tutorial >Detaillierte Erklärung von JavaScript-Verschlüssen_Grundkenntnisse

Detaillierte Erklärung von JavaScript-Verschlüssen_Grundkenntnisse

WBOY
WBOYOriginal
2016-05-16 16:16:09974Durchsuche

Im letzten Artikel haben wir einen Überblick über die Vorinterpretation gegeben, bevor wir diesen Blog-Beitrag geschrieben haben. Da diese Fälle relativ umfangreich sind, haben wir diesen Blog-Beitrag Schritt für Schritt geschrieben Dass wir es können Es ist auch einfacher, mit dem Erlernen und Vertiefen von JavaScript zu beginnen.

Vorwort

Ein Kollege ging zu einem Vorstellungsgespräch und der Interviewer stellte eine Frage: Können Sie einen Abschluss schreiben und mich einen Blick darauf werfen lassen? Also hat mein Kollege schnell den folgenden Code geschrieben:

Code kopieren Der Code lautet wie folgt:

Funktion fn(){
warning('Hallo JavaScript-Abschluss!!!'); // Verdammt, der E-Text ist nicht gut, also musste ich einen Übersetzer finden, der die Abschlusswörter ausschreibt
}
fn();

Dann schüttelte der Interviewer den Kopf und sagte: „Wie kann man das als Abschluss bezeichnen?“ Am Ende konnten die beiden nicht streiten und der Kollege ging entschieden. Was zum Teufel macht der Interviewer? (Diese Geschichte ist rein fiktiv, jede Ähnlichkeit ist rein zufällig)

Abschluss mag in den Augen vieler Menschen eine „hochwertige und schwer zu erlernende“ Technologie sein. Vielleicht ist es in den Augen vieler Menschen die einzige, die als Abschluss zählt:

Beispiel 1:

Code kopieren Der Code lautet wie folgt:

Funktion fn() {
Rückgabefunktion () {
alarm('Beispiel 1');
}
}
fn()();

Beispiel 1 PS: Das sieht nicht sehr fortgeschritten aus, es scheint, als ob diese Person nicht sehr gut ist!

Beispiel 2:

Code kopieren Der Code lautet wie folgt:

;(Funktion () {
alarm('Beispiel 2');
})();

Beispiel 2 PS: Dieses sieht fortgeschrittener aus als das vorherige und vor der ersten Klammer wird ein Semikolon hinzugefügt. Nun, lassen Sie uns diese Frage zunächst hier belassen und später darüber sprechen.

Beispiel 3:

Code kopieren Der Code lautet wie folgt:

~function fn() {
alarm('Beispiel 3')
}();

Beispiel 3 PS: Das ist das fortgeschrittenste, es ist erstaunlich, ich lese nicht viel, also lüg mich nicht an!

Ich lese nicht viel, daher kann ich nur diese drei Arten von „Abschlüssen“ schreiben. Ich glaube, dass andere Blogger jetzt mit meinem Unsinn aufhören und meine Recherche fortsetzen können Ich kenne den Mechanismus der Funktionsoperation. Ich möchte diesen Bereich eigentlich nicht hinzufügen. Alte Gewohnheit, Code zuerst:

Code kopieren Der Code lautet wie folgt:

var n = 10;
Funktion fn(){
alarm(n);
var n = 9;
alarm(n);
}
fn();

Um es einfach auszudrücken: Lassen Sie uns ein Bild zeichnen (der Autor verwendet nur die Zeichensoftware, die mit Windows geliefert wird. Wenn es eine bessere gibt, empfehlen Sie diese bitte), um es zu analysieren:

Analyse 1

Auf dem Bild sehen wir zwei Bereiche, einer ist der Fensterbereich (Bereich der obersten Ebene) und der andere ist ein privater Bereich, der gebildet wird, wenn fn aufgerufen wird. Bei dem Bereich handelt es sich dann tatsächlich um eine Codeausführungsumgebung. Die Lernumgebung eines Schülers ist beispielsweise die Schule, was seinem Spielraum entspricht. Wenn dieser Schüler sehr unartig ist und nachts oft in ein Internetcafé geht, um Spiele zu spielen, ist dies gleichbedeutend mit der Schaffung einer privaten Umgebung, und dieser Spielraum ist der Internetcafé. In Ordnung! Diese Kastanie sieht dem Masturbator selbst so verdammt ähnlich, dass ich nicht anders konnte, als zu seufzen: „Wenn du in jungen Jahren nicht hart arbeitest, wirst du im Erwachsenenalter getreten.“ Zurück zum Thema: Tatsächlich ist die Definition der Funktion fn eine Beschreibung, die auf einen Codeabschnitt verweist (rotes Kästchen im Bild), wenn fn aufgerufen wird (grünes Kästchen im Bild). In diesem Bereich wird der Code auch vor der Ausführung vorinterpretiert. Ich werde Ihnen nicht sagen, dass dieser Bereich nach der Ausführung zerstört wird. und dann wird der Code nach der endgültigen Ausführung zerstört.

Abschlüsse verstehen

Wir wissen, dass eine Funktion beim Aufruf einen privaten Bereich (Ausführungsumgebung) bildet und dieser private Bereich ein Abschluss ist. Ist Closing rückblickend immer noch das legendäre „groß und schwer zu meistern“? Schauen wir uns die erste Interviewgeschichte und die drei Beispiele an, die ich geschrieben habe. Es handelt sich tatsächlich um Abschlüsse. Um genau zu sein, handelt es sich bei diesen drei Beispielen um gängige Formen von Abschlüssen.

Anwendungsszenarien

Jetzt gibt es eine solche Anforderung: Es gibt ein ul-Tag in der HTML-Seite und es gibt 5 li-Tags unter ul. Es ist erforderlich, auf ein beliebiges li und die Indexposition (Index beginnt bei 0) zu klicken Das angeklickte Li wird angezeigt und die HTML-Struktur lautet wie folgt:

Code kopieren Der Code lautet wie folgt:


  • Liste 1

  • Liste 2

  • Liste 3

  • Liste 4

  • Liste 5



Da ich schlau war, habe ich schnell den folgenden Code geschrieben:

Code kopieren Der Code lautet wie folgt:

var lis = document.getElementById('ul').getElementsByTagName('li');
for (var i = 0, len = lis.length; i < len; i ) {
lis[i].onclick = function () {
alarm(i);
};
}

Abschlusstest, um zu sehen, ob diese Anforderung perfekt umgesetzt wird:

Ich habe festgestellt, dass dieses Ergebnis irgendwann angezeigt wird, egal wie oft ich klicke. Das erwartete Ergebnis ist: Klicken Sie auf Liste 1, um 0 anzuzeigen, klicken Sie auf Liste 2, um 1 anzuzeigen, und klicken Sie auf Liste 3, um 0 anzuzeigen Popup 2... Ich möchte dieses Bild in diesem Moment nur verwenden, um meine aktuelle Stimmung zu beschreiben:

(Wie es aussieht, wenn der Prototyp während der Demonstration nicht wie vorgesehen funktioniert)

Wie geht das? Warum erscheint immer 5? Es ist theoretisch richtig! Lassen Sie uns ein Bild zeichnen, um es zu analysieren:

Tatsächlich handelt es sich bei dem Onclick, den wir gerade jedem Li geben, tatsächlich um eine gespeicherte Beschreibungszeichenfolge einer Funktion. Der Inhalt dieser Zeichenfolge ist der Inhalt im roten Feld im Bild oben. Ich habe ein Bild mit der Wahrheit:

Geben Sie Folgendes ein: lis[4].onclick in der Chrome-Konsole, der Wert ist die Funktionsbeschreibung. Wenn wir auf die fünfte Liste klicken, entspricht dies tatsächlich dem Aufruf dieser Funktionsbeschreibung. Wir wissen, dass die Funktion einen privaten Bereich bildet, wenn sie aufgerufen und ausgeführt wird wird ebenfalls zuerst vorinterpretiert und dann wird der Code ausgeführt. Im aktuellen privaten Bereich gibt es kein i, und dann wird im Fensterbereich 5 angezeigt .

Offensichtlich kann der obige Code diese Anforderung nicht erfüllen. Es ist falsch, den Code so zu schreiben. Denken wir über die Ursache des Problems nach. Tatsächlich liegt der Grund darin, dass Sie jedes Mal, wenn Sie klicken, das i unter dem Fenster lesen. Zu diesem Zeitpunkt ist der Wert von i bereits 5, sodass Sie den folgenden Code haben:

Methode 1:

Code kopieren Der Code lautet wie folgt:

var lis = document.getElementById('ul').getElementsByTagName('li');
Funktion fn(i) {
Rückgabefunktion () {
alarm(i);
}
}
for (var i = 0, len = lis.length; i < len; i ) {
lis[i].onclick = fn(i);
}

Methode 2:

Code kopieren Der Code lautet wie folgt:

var lis = document.getElementById('ul').getElementsByTagName('li');

for (var i = 0, len = lis.length; i < len; i ) {
;(Funktion (i) {
          lis[i].onclick = function () {
alarm(i);
        };
})(i);
}

Methode 3:

Code kopieren Der Code lautet wie folgt:

var lis = document.getElementById('ul').getElementsByTagName('li');

for (var i = 0, len = lis.length; i < len; i ) {
lis[i].onclick = Funktion fn(i) {
         Return-Funktion () {
alarm(i);
}
}(i);
}

J'ai écrit trois méthodes d'un seul coup. L'idée est la même, c'est à dire de stocker la variable i dans une variable privée. Ici, je ne parlerai que de la deuxième méthode. Bien sûr, si vous en comprenez une, vous. comprendra le reste. Comme d'habitude, on dessine des images à analyser étape par étape :

J'ai décrit l'intégralité de l'exécution du code en détail. Il convient de noter que l'attribut onclick de chaque li doit occuper la portée (function(i){…})(i) Lorsque cette fonction est exécutée, elle ne le sera pas. être détruit car il est occupé par un li externe (ce li est sous la portée de la fenêtre), donc cette portée ne sera pas détruite. Lorsqu'un li est cliqué, function(){ alert(i); } sera exécuté et une portée sera formée. Cette portée n'a pas de i, et elle ira à (function(){ ... })(. i) scope. Trouvez i, et enfin trouvez i dans le paramètre formel. La valeur de ce paramètre formel i est transmise lors de la boucle for ; cet exemple utilise intelligemment des fermetures pour stocker les valeurs, ce qui résout parfaitement le problème.

PS : je viens de mentionner pourquoi un point-virgule est ajouté devant (function(i){ … })(i). La raison est d'éviter que l'instruction précédente oublie d'ajouter un point-virgule, ce qui provoquerait des erreurs JavaScript lors du processus. analyse. C'est tout. Bien sûr, l'un des scénarios d'application ci-dessus est le principe d'implémentation des onglets. Il peut y avoir d'autres méthodes d'implémentation, telles que les méthodes d'attributs personnalisées et la recherche d'index via les relations entre les nœuds DOM. L'objectif principal de l'utilisation de cette méthode est d'approfondir la compréhension des fermetures. .

Résumé

Les fermetures ne sont pas légendaires et difficiles à maîtriser. L'essentiel est de comprendre la définition et l'appel d'une fonction. Lorsqu'une fonction est appelée, une nouvelle portée privée est formée. cette portée ne sera pas détruite. Lu Zhu a très peu lu, j'aimerais donc demander à mes collègues blogueurs de me corriger si je me trompe. Je voudrais également remercier tout le monde pour leur soutien aux articles de Lu Zhu.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn