Heim > Web-Frontend > js-Tutorial > JavaScript-Bereichskette Teil 2: Funktionslebenszyklus

JavaScript-Bereichskette Teil 2: Funktionslebenszyklus

黄舟
Freigeben: 2016-12-20 16:21:28
Original
1333 Leute haben es durchsucht

Der Lebenszyklus einer Funktion ist in Erstellungs- und Aktivierungsphasen (sofern aufgerufen) unterteilt. Lassen Sie uns ihn im Detail untersuchen.

Funktionserstellung

Wie wir alle wissen, werden Funktionsdeklarationen beim Eintritt in den Kontext in Variablen-/Aktivitätsobjekten (VO/AO) platziert. Schauen wir uns die Variablen- und Funktionsdeklarationen im globalen Kontext an (hier ist das Variablenobjekt das globale Objekt selbst, wir erinnern uns daran, oder?)

var x = 10;
  
function foo() {
  var y = 20;
  alert(x + y);
}
  
foo(); // 30
Nach dem Login kopieren

Bei der Funktionsaktivierung erhalten wir das richtige (erwartete) Ergebnis - 30. Es gibt jedoch eine sehr wichtige Funktion.

Früher haben wir nur über variable Objekte gesprochen, die sich auf den aktuellen Kontext beziehen. Hier sehen wir, dass die Variable „y“ in der Funktion „foo“ definiert ist (was bedeutet, dass sie sich im AO des foo-Kontexts befindet), die Variable „x“ jedoch nicht im „foo“-Kontext definiert ist und dementsprechend es wird nicht zum AO von „foo“ hinzugefügt. Auf den ersten Blick existiert die Variable „x“ relativ zur Funktion „foo“ überhaupt nicht; aber wie wir unten sehen – und nur auf den „Blick“, stellen wir fest, dass das aktive Objekt des „foo“-Kontexts nur enthält ein Attribut – „y“.

fooContext.AO = {
  y: undefined // undefined – 进入上下文的时候是20 – at activation
};
Nach dem Login kopieren

Wie greift die Funktion „foo“ auf die Variable „x“ zu? Theoretisch sollte die Funktion auf das Variablenobjekt eines übergeordneten Kontexts zugreifen können. Tatsächlich ist es genau so. Dieser Mechanismus wird über das Attribut [[scope]] innerhalb der Funktion implementiert.

[[scope]] ist eine hierarchische Kette aller übergeordneten Variablenobjekte, die über dem aktuellen Funktionskontext liegen und darin gespeichert werden, wenn die Funktion erstellt wird.

Beachten Sie diesen wichtigen Punkt – [[scope]] wird gespeichert, wenn die Funktion erstellt wird – statisch (unveränderlich), für immer und ewig, bis die Funktion zerstört wird. Das heißt: Die Funktion kann nie aufgerufen werden, aber das Attribut [[scope]] wurde geschrieben und im Funktionsobjekt gespeichert.

Eine weitere zu berücksichtigende Sache ist, dass [[scope]] im Gegensatz zur Bereichskette ein Attribut der Funktion und nicht des Kontexts ist. Betrachtet man das obige Beispiel, lautet der [[Bereich]] für die Funktion „foo“ wie folgt:

foo.[[Scope]] = [
  globalContext.VO // === Global
];
Nach dem Login kopieren

Zum Beispiel verwenden wir die üblichen ECMAScript-Arrays, um Bereiche und [[Bereich]] darzustellen.

Weiterhin wissen wir, dass der Kontext eingegeben wird, wenn die Funktion aufgerufen wird. Zu diesem Zeitpunkt wird das aktive Objekt erstellt und dieses sowie der Bereich (Bereichskette) bestimmt. Betrachten wir diesen Moment im Detail.

Funktionsaktivierung

Wie in der Definition erwähnt, wird nach Eingabe des Kontexts zum Erstellen von AO/VO das Scope-Attribut des Kontexts (eine Bereichskette für die Variablensuche) wie folgt definiert:

Scope = AO|VO + [[Scope]]
Nach dem Login kopieren

Die Bedeutung des obigen Codes ist: Das aktive Objekt ist das erste Objekt des Bereichsarrays, das dem vorderen Ende des Bereichs hinzugefügt wird.

Scope = [AO].concat([[Scope]]);
Nach dem Login kopieren

Diese Funktion ist wichtig für die Verarbeitung des Identifier-Parsings. Bei der Bezeichnerauflösung wird ermittelt, zu welchem ​​Variablenobjekt eine Variable (oder Funktionsdeklaration) gehört.

Im Rückgabewert dieses Algorithmus haben wir immer einen Referenztyp, seine Basiskomponente ist das entsprechende Variablenobjekt (oder null, wenn nicht gefunden) und die Attributnamenkomponente ist der Name des zu verwendenden Bezeichners schaute nach. Einzelheiten zu Referenztypen werden später besprochen.

Der Identifier-Auflösungsprozess besteht aus einer Suche nach den Attributen, die dem Variablennamen entsprechen, d. h. einer kontinuierlichen Suche nach den Variablenobjekten im Bereich, beginnend im tiefsten Kontext und unter Umgehung der Bereichskette nach oben .

Auf diese Weise haben bei der Aufwärtssuche lokale Variablen in einem Kontext eine höhere Priorität als Variablen im übergeordneten Bereich. Falls zwei Variablen denselben Namen haben, aber aus unterschiedlichen Bereichen stammen, befindet sich die erste gefundene Variable im tiefsten Bereich.

Wir verwenden ein etwas komplizierteres Beispiel, um zu beschreiben, was wir oben erwähnt haben.

var x = 10;
  
function foo() {
  var y = 20;
  
  function bar() {
    var z = 30;
    alert(x +  y + z);
  }
  
  bar();
}
  
foo(); // 60
Nach dem Login kopieren

Dazu haben wir die folgenden Variablen/Aktivitäten, das [[scope]]-Attribut der Funktion und die Scope-Kette des Kontexts:

Das Variablenobjekt des Global Kontext ist:

globalContext.VO === Global = {
  x: 10
  foo: <reference to function>
};
Nach dem Login kopieren

Wenn „foo“ erstellt wird, ist das [[scope]]-Attribut von „foo“:

foo.[[Scope]] = [
  globalContext.VO
];
Nach dem Login kopieren

Wenn „foo“ aktiviert ist (in den Kontext gelangt). ), „foo“ „Das aktive Objekt des Kontexts ist:

fooContext.AO = {
  y: 20,
  bar: <reference to function>
};
Nach dem Login kopieren

Die Bereichskette des „foo“-Kontexts ist:

fooContext.Scope = fooContext.AO + foo.[[Scope]] // i.e.:
  
fooContext.Scope = [
  fooContext.AO,
  globalContext.VO
];
Nach dem Login kopieren

Wenn die interne Funktion „bar“ erstellt wird, ist sein [[Bereich]]:

bar.[[Scope]] = [
  fooContext.AO,
  globalContext.VO
];
Nach dem Login kopieren

Wenn „bar“ aktiviert ist, ist das aktive Objekt des „bar“-Kontexts:

barContext.AO = {
  z: 30
};
Nach dem Login kopieren

Die Bereichskette des „bar“-Kontexts ist:

barContext.Scope = barContext.AO + bar.[[Scope]] // i.e.:
  
barContext.Scope = [
  barContext.AO,
  fooContext.AO,
  globalContext.VO
];
Nach dem Login kopieren

Die Bezeichner von „x“, „y“ und „z“ werden wie folgt analysiert:

- "x"
-- barContext.AO // not found
-- fooContext.AO // not found
-- globalContext.VO // found - 10
 
- "y"
-- barContext.AO // not found
-- fooContext.AO // found - 20
 
- "z"
-- barContext.AO // found - 30
Nach dem Login kopieren

Das Obige ist das Zweiter Teil der JavaScript-Bereichskette: Der Inhalt des Lebenszyklus der Funktion, mehr verwandt. Bitte beachten Sie den Inhalt der chinesischen PHP-Website (m.sbmmt.com)!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage