VorwortWenn Sie ein qualifizierter Front-End-Entwickler sind oder werden möchten, müssen Sie den Ausführungsprozess von JavaScript-Code kennen, den Ausführungskontext, den Umfang, die Variablenförderung und andere verwandte Konzepte kennen und diese geschickt auf Ihren eigenen Code anwenden. Dieser Artikel bezieht sich auf „JavaScript, das Sie nicht kennen“, „Erweiterte JavaScript-Programmierung“ und einige Blogs. Text1. Konzepte im Zusammenhang mit dem Ausführungsprozess von JavaScript-CodeDie Ausführung von JS-Code ist in zwei Phasen unterteilt: Compiler-Kompilierung und JS-Engine- und Bereichsausführung. Die Compiler-Kompilierungsphase (Vorkompilierungsphase) ist in drei Phasen unterteilt: Wortsegmentierung/lexikalische Analyse, Parsing/syntaktische Analyse und Codegenerierung. (1) In der Phase der Wortsegmentierung/lexikalischen Analyse ist der Compiler für die Segmentierung des Codes und die Aufteilung der Anweisungen in lexikalische Einheitsströme/Arrays verantwortlich. (2) In der Parsing-/Lexikalanalysephase wird der lexikalische Einheitenstrom der vorherigen Phase in einen abstrakten Syntaxbaum umgewandelt, der aus verschachtelten Elementen besteht, die der grammatikalischen Struktur des Programms entsprechen. (3) In der Codegenerierungsphase wird der abstrakte Syntaxbaum in ausführbaren Code umgewandelt und an die JS-Engine übermittelt. Drei wichtige Rollen der JS-Codeausführung: (1) JS-Engine: verantwortlich für den gesamten Prozess der Codeausführung (2) Compiler: verantwortlich für die Analyse der JS-Codesyntax und die Generierung von ausführbarem Code (3) Geltungsbereich: Erfassen und Verwalten aller deklarierten Kennungen und Festlegen der Zugriffsrechte des aktuellen Codes auf die deklarierten Kennungen nach bestimmten Regeln. 2. Ausführungskontext und AusführungsstapelImmer wenn JavaScript-Code ausgeführt wird, wird er in einem Ausführungskontext ausgeführt. Wenn es um den Ausführungskontext geht, müssen Sie wissen, was der Ausführungsstapel ist. Der Ausführungsstapel, der in anderen Programmiersprachen der „Aufrufstapel“ ist, ist ein Stapel mit einer LIFO-Datenstruktur (Last In, First Out), der zum Speichern des Ausführungskontexts verwendet wird, der beim Ausführen des Codes erstellt wird. Wenn die JS-Engine den auszuführenden Code zum ersten Mal findet, erstellt sie zunächst einen globalen Ausführungskontext und schiebt ihn in den aktuellen Ausführungsstapel. Immer wenn die Engine auf einen Funktionsaufruf stößt, erstellt sie einen neuen Ausführungskontext für die Funktion und schiebt ihn an den Anfang des Stapels. Die JS-Engine führt die Funktion am Anfang des Stapels aus. Wenn die Funktion ausgeführt wird, wird der Ausführungskontext vom Stapel entfernt und der Kontrollfluss erreicht den nächsten Kontext. Jeder Ausführungskontext enthält drei wichtige Eigenschaften: variables Objekt, Bereichskette und dies. Auch diese Eigenschaften müssen gründlich verstanden werden. 2.1 Kontextaufrufstapelvar scope1 = "globaler Bereich"; Funktion checkscope1(){ var scope1 = "lokaler Bereich"; Funktion f(){ konsole.log(Bereich1); } Rückgabewert f(); } Prüfumfang1(); var scope2 = "globaler Bereich"; Funktion checkscope2(){ var scope2 = "lokaler Bereich"; Funktion f(){ konsole.log(Bereich2); } Rückgabe f; } checkscope2()(); Beide der oben genannten Codeausschnitte geben lokalen Umfang aus Im obigen Code muss der Gültigkeitsbereich eine lokale Variable sein. Sie können den Gültigkeitsbereich auf Blockebene finden. Unabhängig davon, wann und wo f() ausgeführt wird, ist diese Bindung immer noch gültig, wenn f() ausgeführt wird. Es tritt das gleiche Ergebnis auf, allerdings sind die Änderungen im Ausführungskontextstapel der beiden Codesegmente unterschiedlich: Der erste Code: push(<checkscope1>functionContext)=>push(<f>functionContext)=>pop()=>pop() Der zweite Code: push(<checkscope2>functionContext)=>pop()=>push(<f>functionContext)=>pop() 2.2 Drei Arten von Ausführungskontexten(1) Globaler Kontext Wenn die JS-Engine mit der Analyse des JS-Codes beginnt, stößt sie als Erstes auf den globalen Code. Während der Initialisierung wird ein globaler Ausführungskontext in den Aufrufstapel geschoben. Der Ausführungskontextstapel wird gelöscht, wenn die gesamte Anwendung beendet wird. Ganz unten im Stapel befindet sich immer der globale Ausführungskontext. Dies ist der standardmäßige oder grundlegende globale Gültigkeitsbereich. Der Code innerhalb jeder Funktion befindet sich im globalen Gültigkeitsbereich. Zuerst wird ein globales Fensterobjekt erstellt und dann wird dessen Wert auf den des globalen Objekts gesetzt. In einem Programm gibt es nur einen globalen Ausführungskontext. Im JS-Code der obersten Ebene können Sie damit auf das globale Objekt verweisen, da das globale Objekt der Kopf der Domänenkette ist, was bedeutet, dass alle nicht qualifizierten Variablen und Funktionen als Funktionen dieses Objekts abgefragt werden. Kurz gesagt, es gibt nur einen globalen Ausführungskontext, der im Allgemeinen vom Browser im Client erstellt wird, nämlich das uns bekannte Fensterobjekt, und über dieses können wir direkt darauf zugreifen. (2) Funktionskontext Immer wenn eine Funktion aufgerufen wird, wird ein neuer Kontext für diese Funktion erstellt. Jede Funktion hat ihren eigenen Kontext, der beim Aufruf der Funktion erstellt wird. Es ist zu beachten, dass ein neuer Kontext erstellt wird, wenn dieselbe Funktion mehrmals aufgerufen wird. (3) eval und mit Kontext Innerhalb von eval und mit Funktionen ausgeführter Code verfügt ebenfalls über einen eigenen Ausführungskontext. Da JavaScript-Entwickler eval jedoch nicht sehr häufig verwenden, werde ich hier nicht näher darauf eingehen. 2.3 Phase der Erstellung des Ausführungskontexts Die Erstellung des Ausführungskontexts ist in zwei Phasen unterteilt: Erstellungsphase und Ausführungsphase. Die JS-Engine ist während der Erstellungsphase des Ausführungskontexts hauptsächlich für drei Dinge verantwortlich: Dies bestimmen ==> Erstellen einer lexikalischen Umgebungskomponente ==> Erstellen einer variablen Umgebungskomponente (ich verstehe es noch nicht ganz) (1) Bestimmen Sie dies, was nicht im Detail erklärt wird (2) Erstellen Sie eine lexikalische Umgebungskomponente Eine lexikalische Umgebung ist ein Spezifikationstyp, der die Zuordnung von Bezeichnern zu bestimmten Variablen und Funktionen basierend auf der lexikalischen Verschachtelungsstruktur von ECMAScript-Code definiert. Eine lexikalische Umgebung besteht aus einem Umgebungsrekorder und einem möglicherweise leeren Wert, der auf eine äußere lexikalische Umgebung verweist. Der Umgebungsdatensatz wird verwendet, um den tatsächlichen Speicherort von Variablen und Funktionsdeklarationen in der aktuellen Umgebung zu speichern. Der Einführungsdatensatz für externe Umgebungen ist leicht zu verstehen. Er wird verwendet, um andere externe Umgebungen zu speichern, auf die von der eigenen Umgebung aus zugegriffen werden kann. Hat er in diesem Zusammenhang also eine gewisse Bedeutung für die Gültigkeitsbereichskette? Es gibt zwei Arten von lexikalischen Umgebungen:
(3) Erstellen Sie variable Umgebungskomponenten Die variable Umgebung kann auch als lexikalische Umgebung bezeichnet werden. Sie verfügt über alle Eigenschaften einer lexikalischen Umgebung und hat außerdem Umgebungsdatensätze und externe Umgebungseinführungen. Der einzige Unterschied in ES6 besteht darin, dass die lexikalische Umgebung zum Speichern von Funktionsdeklarationen und mit let const deklarierten Variablen verwendet wird, während die Variablenumgebung nur mit var deklarierte Variablen speichert. 3. JavaScript-Bereich und Bereichskette3.1 GeltungsbereichDer lexikalische Gültigkeitsbereich wird beim Schreiben oder Definieren von Code bestimmt, während der dynamische Gültigkeitsbereich zur Laufzeit bestimmt wird. (Dies ist auch der Fall.) Der lexikalische Gültigkeitsbereich konzentriert sich darauf, wo die Funktion deklariert wird, während der dynamische Gültigkeitsbereich sich darauf konzentriert, von wo aus die Funktion aufgerufen wird. JavaScript verwendet einen lexikalischen Gültigkeitsbereich, und sein Gültigkeitsbereich wird dadurch bestimmt, wo Sie beim Schreiben des Codes die Variablen und den Blockgültigkeitsbereich schreiben, sodass der Gültigkeitsbereich unverändert bleibt, wenn der lexikalische Analysator den Code verarbeitet. Man kann davon ausgehen, dass der Umfang ein unabhängiges Gebiet ist, das das Durchsickern oder die Offenlegung von Variablen verhindert. Mit anderen Worten, der größte Nutzen des Bereichs besteht in der Isolierung von Variablen, und es kommt nicht zu Konflikten zwischen Variablen mit demselben Namen in unterschiedlichen Bereichen. Schauen wir uns eine Frage an, bevor wir den Umfang verstehen Funktion foo() { konsole.log(Wert); } Var-Wert = 1; Funktion bar() { Var-Wert = 2; konsole.log(Wert); foo(); } Bar(); Was gibt der obige Code aus? Zuerst werden die Funktion foo(), die Variable value (deren Wert nicht definiert ist) und die Funktion bar() im globalen Kontext deklariert. Während der Codeausführungsphase wird der Kontext der Funktion bar auf den Stapel geschoben und ausgeführt, und der Wert wird als 2 ausgegeben. Dann wird foo() ausgeführt und foo() auf den Stapel geschoben. Beim Drucken des Werts kann die Variable nicht gefunden werden, daher sucht die JS-Engine nach dem oberen Bereich, also dem globalen Bereich, und gibt 1 aus. Nachdem die Funktion ausgeführt wurde, wird der Kontext aus dem Stapel entfernt. Schauen wir uns die folgende Funktion an. Der Gültigkeitsbereich ist mehrschichtig. Der innere Gültigkeitsbereich kann auf die Variablen des äußeren Gültigkeitsbereichs zugreifen, aber nicht umgekehrt. Seit ES6 werden die Bereiche in js in globalen Bereich, Funktionsumfang, Blockbereich und Täuschungsbereich unterteilt. 3.1.1 Globaler Geltungsbereich Objekte, auf die von überall im Code zugegriffen werden kann, haben einen globalen Gültigkeitsbereich, die äußerste Funktion und Variablen, die außerhalb der äußersten Funktion definiert sind, haben einen globalen Gültigkeitsbereich und alle undefinierten und direkt zugewiesenen Variablen werden automatisch als Variablen mit globalem Gültigkeitsbereich deklariert. 3.1.2 Funktionsumfang Funktionsumfang bedeutet, dass alle zu dieser Funktion gehörenden Variablen innerhalb des Umfangs der gesamten Funktion verwendet und wiederverwendet werden können (tatsächlich können sie auch in verschachtelten Bereichen verwendet werden). 3.2 GeltungsbereichsketteBei der Bereichskette handelt es sich im Wesentlichen um einen Regelsatz zum Nachschlagen von Variablen (Bezeichnernamen) anhand des Namens. Die Regel ist ganz einfach. Wenn eine Variable nicht in ihrem eigenen Variablenobjekt gefunden werden kann, wird im übergeordneten Variablenobjekt gesucht. Wenn sie den äußersten globalen Kontext erreicht, wird der Suchvorgang beendet, unabhängig davon, ob sie gefunden wird oder nicht. Die Suche wird beendet, wenn die erste passende Variable gefunden wird. Dies wird als Shadowing bezeichnet. Der Zweck der Bereichskette besteht darin, einen geordneten Zugriff auf alle Variablen und Funktionen sicherzustellen, auf die die Ausführungsumgebung Zugriff hat. 4. Der Unterschied zwischen Ausführungskontext und UmfangJedem Funktionsaufruf ist ein Gültigkeitsbereich und ein Kontext zugeordnet. Der Umfang ist grundsätzlich funktionsbasiert und der Kontext objektbasiert. Mit anderen Worten: Der Gültigkeitsbereich bestimmt, wie bei jedem Funktionsaufruf auf Variablen zugegriffen wird, und jeder Aufruf ist unabhängig. Der Kontext ist immer der Wert des Schlüsselworts this, welches eine Referenz auf das Objekt darstellt, das den aktuell ausführbaren Code aufgerufen hat. Der Umfang wird bei der Definition der Funktion festgelegt. Die Variablen in der Funktion beziehen sich auf den Umfang der Funktion, und der Umfang, in dem die Funktion ausgeführt wird, bezieht sich auch auf den Umfang bei der Definition der Funktion. Der Kontext bezieht sich hauptsächlich auf den Wert des Schlüsselworts this, der beim Ausführen der Funktion bestimmt wird. Einfach ausgedrückt bezieht sich this auf denjenigen, der diese Funktion aufruft. 5. ZuletztOben finden Sie eine detaillierte Zusammenfassung des Ausführungskontexts und -umfangs von JS. Weitere Informationen zum Ausführungskontext und -umfang von JS finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Tutorial zum Kompilieren und Installieren von MySQL 5.7.17 aus dem Quellcode auf dem Mac
>>: Beispiel für die Verwendung von Docker Swarm zum Erstellen eines verteilten Crawler-Clusters
Datensortierung aufsteigend, absteigend 1. Sortie...
1. Grundlegende Verwendung Es kann über den Mutat...
In diesem Artikel wird der spezifische Code von J...
Inhaltsverzeichnis Definition Struktur Beispiele ...
Besonderer Hinweis: Dieser Artikel wurde basieren...
Da die in der MySQL-Datenbank gespeicherten Daten...
Gemeinsame Eigenschaften von Tabellen Die grundle...
Inhaltsverzeichnis 1. Unzip-Befehl 1.1 Syntax 1.2...
In diesem Artikel wird die Vant Uploader-Komponen...
Der detaillierte Prozess zum Konfigurieren des My...
In diesem Artikelbeispiel wird der spezifische Co...
Die Verwendung von Schriftarten im Web ist sowohl ...
Dieser Artikel beschreibt den MySQL-Show-Vorgang ...
Was ist der Zweck der Erstellung einer eigenen Web...
Bei der Verwendung von Docker-Compose für die Ber...