Heim >Web-Frontend >js-Tutorial >Ein Klischee über native JS-Ausführungsumgebung und -umfang
Zunächst müssen wir wissen, dass Ausführungsumgebung und Umfang zwei völlig unterschiedliche Konzepte sind.
Jeder Aufruf einer Funktion hat einen eng damit verbundenen Umfang und eine Ausführungsumgebung. Grundsätzlich basiert der Umfang auf Funktionen, während die Ausführungsumgebung auf Objekten basiert (Beispiel: Die globale Ausführungsumgebung ist das Fensterobjekt).
Mit anderen Worten, der Bereich umfasst den Variablenzugriff in der aufgerufenen Funktion, und verschiedene Aufrufszenarien sind unterschiedlich. Die Ausführungsumgebung ist immer der Wert des Schlüsselworts this, das eine Referenz auf das Objekt ist, das den aktuell ausgeführten Code besitzt. Jeder Ausführungsumgebung ist ein Variablenobjekt zugeordnet, und alle in der Umgebung definierten Variablen und Funktionen werden in diesem Objekt gespeichert. Obwohl der von uns geschriebene Code keinen Zugriff auf dieses Objekt hat, verwendet der Parser es im Hintergrund bei der Verarbeitung der Daten.
Ausführungsumgebung (auch Ausführungskontext genannt)
Wenn der JavaScript-Interpreter den Ausführungscode initialisiert, gelangt er standardmäßig zunächst in die globale Ausführungsumgebung Die Funktion erstellt eine neue Ausführungsumgebung.
Jede Funktion hat ihre eigene Ausführungsumgebung. Wenn der Ausführungsfluss in eine Funktion eintritt, wird die Umgebung der Funktion in einen Ausführungsstapel verschoben. Nachdem die Funktion ausgeführt wurde, öffnet der Stapel seine Umgebung und gibt die Kontrolle an die vorherige Ausführungsumgebung zurück. Der Ausführungsfluss in ECMAScript-Programmen wird durch diesen praktischen Mechanismus gesteuert.
Die Ausführungsumgebung kann in zwei Phasen unterteilt werden: Erstellung und Ausführung. In der Erstellungsphase erstellt der Parser zunächst ein Variablenobjekt (auch Aktivierungsobjekt genannt), das aus Variablen, Funktionsdeklarationen und Parametern besteht, die in der Ausführungsumgebung definiert sind. In dieser Phase wird die Bereichskette initialisiert und der Wert dieser wird finalisiert. Während der Ausführungsphase wird der Code interpretiert und ausgeführt.
Demo:
<script type="text/javascript"> function Fn1(){ function Fn2(){ alert(document.body.tagName);//BODY //other code... } Fn2(); } Fn1(); //code here </script>
Zusammenfassung
Wenn der Javascript-Code vom Browser geladen wird, ist der erste, der eingegeben wird, von Standardmäßige globale Ausführungsumgebung. Wenn eine Funktion in der globalen Ausführungsumgebung aufgerufen und ausgeführt wird, tritt der Programmfluss in die aufgerufene Funktion ein. Zu diesem Zeitpunkt erstellt die JS-Engine eine neue Ausführungsumgebung für die Funktion und schiebt sie an die Spitze des Ausführungsumgebungsstapels. Der Browser führt immer die Ausführungsumgebung aus, die sich derzeit an der Spitze des Stapels befindet. Sobald die Ausführung abgeschlossen ist, wird die Ausführungsumgebung von der Oberseite des Stapels entfernt und dann in die Ausführungsumgebung darunter eingegeben, um den Code auszuführen. Auf diese Weise werden die Ausführungsumgebungen im Stapel nacheinander ausgeführt und vom Stapel entfernt, bis sie zur globalen Ausführungsumgebung zurückkehren.
Beachten Sie außerdem einige Punkte:
Einzelner Thread
Synchronisierte Ausführung
Die einzige globale Ausführungsumgebung
Lokale Ausführung Umgebung Es gibt keine Begrenzung für die Anzahl von
Jedes Mal, wenn eine Funktion aufgerufen wird, wird eine neue lokale Ausführungsumgebung dafür erstellt. Auch wenn es sich um eine eigene Funktion handelt, die mehrmals aufgerufen wird (d. h. a Wird die Funktion mehrmals aufgerufen, werden mehrere verschiedene lokale Ausführungsumgebungen erstellt.
Bereich
Wenn Code in einer Umgebung ausgeführt wird, wird eine Bereichskette variabler Objekte erstellt. Der Zweck einer Bereichskette besteht darin, einen geordneten Zugriff auf alle Variablen und Funktionen sicherzustellen, auf die die Ausführungsumgebung Zugriff hat.
Die Bereichskette enthält die variablen Objekte, die jeder Ausführungsumgebung im Ausführungsumgebungsstapel entsprechen. Über die Bereichskette können Sie den Zugriff von Variablen und die Auflösung von Bezeichnern bestimmen.
Hinweis: Das variable Objekt der globalen Ausführungsumgebung ist immer das letzte Objekt in der Bereichskette.
Beim Zugriff auf Variablen muss ein Sichtbarkeitsproblem vorliegen (die innere Umgebung kann auf die Variablen und Funktionen in der äußeren Schicht zugreifen, aber die äußere Umgebung kann nicht auf die Variablen und Funktionen in der inneren Schicht zugreifen). Um tiefer zu gehen: Beim Zugriff auf eine Variable oder beim Aufrufen einer Funktion erstellt die JavaScript-Engine eine verknüpfte Liste aus Variablenobjekten in verschiedenen Ausführungsumgebungen. Beim Zugriff auf eine Variable sucht sie zunächst nach dem ersten Variablenobjekt in der verknüpften Liste Wenn es nicht gefunden wird, suchen Sie weiter nach dem zweiten variablen Objekt, bis das variable Objekt der globalen Ausführungsumgebung, also das Fensterobjekt, gefunden wird. Daraus entstand auch das Konzept der Scope Chain.
Das Bereichskettendiagramm drückt deutlich die Beziehung zwischen der Ausführungsumgebung und dem Bereich (Eins-zu-eins-Korrespondenz) sowie die Beziehung zwischen den Bereichen (verknüpfte Listenstruktur, Top-Down-Beziehung) aus ).
Demo:
var color = "blue"; function changeColor(){ var anotherColor = "red"; function swapColors(){ var tempColor = anotherColor; anotherColor = color; color = tempColor; // 这里可以访问color, anotherColor, 和 tempColor } // 这里可以访问color 和 anotherColor,但是不能访问 tempColor swapColors(); } changeColor(); // 这里只能访问color console.log("Color is now " + color);
Der obige Code enthält insgesamt drei Ausführungsumgebungen: globale Ausführungsumgebung, lokale Ausführungsumgebung von changeColor( ), Die lokale Ausführungsumgebung von swapColors().
Die globale Umgebung hat eine Variable color und eine Funktion changecolor();
Die lokale Umgebung der Funktion changecolor() hat ein anothercolor-Attribut und eine Swapcolors-Funktion kann sowohl auf sich selbst als auch auf Variablen in seiner Peripherie (d. h. in der globalen Umgebung) zugreifen;
Die Funktion swapcolor() verfügt über eine Variable tempcolor in der lokalen Umgebung. Auf alle Variablen in den beiden oben genannten Umgebungen (changecolor und window) kann innerhalb dieser Funktion zugegriffen werden, da diese beiden Umgebungen ihre übergeordneten Ausführungsumgebungen sind.
Die Bereichskette des obigen Codes ist wie folgt:
从上图发现。内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中的任何变量和函数。
标识符解析(变量名或函数名搜索)是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后(全局执行环境)回溯,直到找到标识符为止。
执行环境与作用域的区别与联系
执行环境为全局执行环境和局部执行环境,局部执行环境是函数执行过程中创建的。
作用域链是基于执行环境的变量对象的,由所有执行环境的变量对象(对于函数而言是活动对象,因为在函数执行环境中,变量对象是不能直接访问的,此时由活动对象(activation object,缩写为AO)扮演VO(变量对象)的角色。)共同组成。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途:是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。
小练习
<script type="text/javascript"> (function(){ a= 5; console.log(window.a);//undefined var a = 1;//这里会发生变量声明提升 console.log(a);//1 })(); </script>
window.a之所以是undefined,是因为var a = 1;发生了变量声明提升。相当于如下代码:
<script type="text/javascript"> (function(){ var a;//a是局部变量 a = 5;//这里局部环境中有a,就不会找全局中的 console.log(window.a);//undefined a = 1;//这里会发生变量声明提升 console.log(a);//1 })(); </script>