So starten Sie schnell mit VUE3.0: Einstieg ins Lernen
Verwandte Empfehlungen: JavaScript-Tutorials
Wir hören wahrscheinlich oft „Ausführungsumgebung“, „Umfang“, „Prototyp (Kette)“, „Ausführungskontext“ usw. Was beschreiben sie?
Wir wissen, dass JS eine schwach typisierte Sprache ist und der Variablentyp erst zur Laufzeit bestimmt wird. Wenn die JS-Engine den JS-Code ausführt, führt sie auch eine lexikalische Analyse , Syntaxanalyse , semantische Analyse und andere Verarbeitungen von oben nach unten durch und generiert nach Abschluss der Codeanalyse einen AST (abstrakten Syntaxbaum) und generiert schließlich Maschinencode dass die CPU basierend auf dem AST ausführen und ausführen kann.
Darüber hinaus führt die JS-Engine beim Ausführen des Codes auch andere Verarbeitungen durch. Beispielsweise gibt es in V8 zwei Phasen:
Dies führt dazu zwei Konzepte: „Ausführungskontext“ und „Bereichskette“.
Aus dem Obigen können wir wissen: Wenn js-Code einen ausführbaren Code ausführt, wird der entsprechende Ausführungskontext erstellt.
Zunächst gibt es ein Konzept, das dem ausführbaren Code in js entspricht: „Ausführungsumgebung“ – globale Umgebung, Funktionsumgebung und eval
.
Zweitens gibt es für jeden Ausführungskontext drei wichtige Attribute:
Schauen wir uns zwei Codeteile an:
varscope="globalscope"{; var Scope="Lokaler Bereich"; Funktion f(){ Rückgabebereich; } return f();}checkscope();
var Scope="globaler Bereich";function checkscope(){ var Scope="Lokaler Bereich"; Funktion f(){ Rückgabebereich; } return f;}checkscope()();
Was werden sie ausgeben?
Warum? Die Antwort ist, dass ihre Ausführungskontextstapel unterschiedlich sind!
Was ist der „Ausführungskontextstapel“?
Bei der Ausführung eines ausführbaren Codes werden im Vorfeld Vorbereitungen getroffen. Die „Vorbereitungen“ werden hier professionell als „Ausführungskontext“ bezeichnet. Aber wie kann man angesichts der Zunahme von ausführbarem Code wie Funktionen so viele Ausführungskontexte verwalten? Daher hat die JS-Engine das Konzept des Ausführungskontextstapels entwickelt.
Wir können ein Array vollständig verwenden, um sein Verhalten zu simulieren (es gibt immer einen globalen Ausführungskontext globalContext am Ende des Stapels).
Wir definieren zuerst einen
EStack=[globalContext]
und simulieren dann den ersten Codeteil:
EStack. push(<checkscope> functionContext); EStack.push(<f> functionContext);EStack.pop();EStack.pop();
Und der zweite Code sieht so aus:
EStack.push(<checkscope> functionContext); EStack.pop();EStack.push (<f> functionContext);EStack.pop();
Der Grund dafür ist, dass Sie möglicherweise zuerst das Konzept des „Abschlusses“ studieren müssen!
Übrigens, wie erreicht man bei der „Front-End-Modularisierung“ eine „langfristige Datenspeicherung“?
Cache? NEIN. Schließung!
Zunächst einmal bezieht sich der Bereich auf den Bereich im Programm, in dem Variablen definiert sind. Der Bereich gibt an, wie die Variable gefunden wird, wodurch die Zugriffsrechte des aktuell ausgeführten Codes auf die Variable bestimmt werden.
Es gibt zwei Arten von Bereichen: statischer Bereich und dynamischer Bereich .
Der von JS verwendete statische Bereich wird auch als „lexikalischer Bereich“ bezeichnet. Der Umfang einer Funktion wird bestimmt, wenn die Funktion definiert wird.
Aus dem oben Gesagten geht hervor, dass Variablen im lexikalischen Bereich während des Kompilierungsprozesses einen bestimmten Gültigkeitsbereich haben. Dieser Bereich ist der „aktuelle Ausführungskontext“. Nach ES5 verwenden wir „lexikalische Umgebung“ anstelle von Bereich, um den Ausführungskontext zu beschreiben. Die lexikalische Umgebung besteht aus zwei Mitgliedern:
Schauen wir uns noch ein Beispiel an:
var value=1 ;Funktion foo(){ console.log(value);}function bar(){ var-Wert=2; foo();}bar();
Was soll im Rückblick auf die obige Definition gedruckt werden?
Lassen Sie uns den Ausführungsprozess analysieren:
Führen Sie die Funktion foo() aus und suchen Sie zunächst innerhalb der Funktion foo, ob ein lokaler Variablenwert vorhanden ist. Wenn nicht, suchen Sie den Code auf der oberen Ebene basierend auf der Position, an der er definiert wurde, d. h. Wert=1. Das Ergebnis wird also als 1 gedruckt.
Dies ist natürlich nicht so einfach und kann aus der Perspektive des Ausführungskontexts zusammengefasst werden.
Oben haben wir über die beiden Komponenten der lexikalischen Umgebung (Scope) gesprochen. In Kombination mit dem Ausführungskontext ist es nicht schwer zu erkennen, dass durch den Verweis auf die externe lexikalische Umgebung der Umfang Schicht für Schicht entlang des Stapels erweitert werden kann, wodurch eine Kettenstruktur entsteht, die sich von der aktuellen Umgebung nach außen erstreckt.
Schauen wir uns ein anderes Beispiel an:
function foo(){ console.dir(bar); var a=1; Funktionsleiste(){ a=2; }}console.dir(foo);foo();Aus dem statischen Bereich erstellt die globale Funktion foo ein [[scope]
]
[[scope]]
Attribut ihres eigenen Objekts
foo[[scope]]=[globalContext];
(), Es werden auch nacheinander der Definitionszeitraum und der Ausführungszeitraum der Foo-Funktion eingegeben.
Während des Definitionszeitraums der foo-Funktion umfasst der [[scope]] der Funktionsleisteden
[[scope]]
integrierten Bereich und den integrierten Bereich von foo
bar[[scope]]=[fooContext,globalContext];
Dieser Punkt: „JS wird übergeben Externe lexikalische Umgebungsreferenzen werden verwendet, um eine Bereichskette variabler Objekte zu erstellen und so den geordneten Zugriff auf Variablen und Funktionen sicherzustellen, auf die die Ausführungsumgebung Zugriff hat.“
Kehren wir zur Frage im Ausführungskontext zurück: Was ist der Unterschied zwischen ihnen? Lassen Sie uns darüber sprechen, warum sie „lokalen Bereich“ auf die gleiche Weise ausgeben: Es ist immer noch derselbe Satz: „JS verwendet den lexikalischen Bereich, und der Umfang der Funktion hängt vom Ort ab, an dem die Funktion erstellt wird.“ ” – Ausführung der JS-Funktion Es wird eine Bereichskette verwendet, die erstellt wird, wenn die Funktion definiert wird. Die verschachtelte Funktion f() ist in dieser Bereichskette definiert und der darin enthaltene Variablenbereich muss sich auf lokale Variablen beziehen. Unabhängig davon, wann und wo f() ausgeführt wird, ist diese Bindung weiterhin gültig, wenn f() ausgeführt wird.
Wenn eine Variable nicht in ihrem eigenen lexikalischen Umgebungsdatensatz gefunden werden kann, kann sie auf der Grundlage der externen lexikalischen Umgebungsreferenz auf der äußeren Ebene durchsucht werden, bis die externe lexikalische Umgebungsreferenz in der äußersten lexikalischen Umgebung null
ist.
Ähnlich verhält es sich mit der „Suche basierend auf der Prototypenkette in Objekten“:
__proto__
ist null)Der Unterschied ist ebenfalls offensichtlich: Die Prototypkette ist ein Link, der die Objektvererbung über das Prototypattribut herstellt, während sich die Bereichskette auf den Abschluss bezieht, der internen Funktionen den Zugriff auf externe Funktionen ermöglicht. Ob direkt oder indirekt, alle Funktionsbereichsketten sind letztendlich mit dem globalen Kontext verknüpft.
Verwandte Empfehlungen: JavaScript-Lern-Tutorial.
Das Obige ist ein detailliertes Verständnis dafür, wie die JavaScript-Engine JS-Code ausführt. Weitere Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website.