Heim  >  Artikel  >  Web-Frontend  >  Ein Artikel über den Ausführungskontext in Javascript

Ein Artikel über den Ausführungskontext in Javascript

青灯夜游
青灯夜游nach vorne
2023-02-14 19:41:062313Durchsuche

In diesem Artikel geht es um den Ausführungskontext in Javascript und um eine Denkfrage. Durch die Analyse der Denkfrage werden Sie sicherlich ein tieferes Verständnis des Ausführungskontexts erhalten.

Ein Artikel über den Ausführungskontext in Javascript

In den vorherigen Artikeln haben wir ein detailliertes Verständnis der drei wichtigen Elemente des Ausführungskontexts erhalten: variable Objekte, Bereichsketten und dies. Dieser Artikel ist eine Sammlung und Zusammenfassung der Inhalte der ersten vier Artikel . Führen Sie eine einfache Konsolidierung verstreuter Wissenspunkte durch. Ich weiß nicht, ob jemand aus dem vorherigen Artikel hierher gekommen ist. Durch die Analyse der Frage werde ich auf jeden Fall ein tieferes Verständnis des Ausführungskontexts erlangen.

Denkfragen

Um den Fall etwas komplizierter zu machen, wurden einige Änderungen vorgenommen, die in der ursprünglichen Frage untersuchten Punkte wurden jedoch nicht geändert.

function func(value){
    getValue = function(){
        console.log(value);
    };
    return this
}
            
function getValue(){
    console.log(5);
}

Func(1).getValue(); //为什么是1呢?

Spezifische Ausführungsanalyse

Führen Sie globalen Code aus, erstellen Sie einen globalen Ausführungskontext, der globale Kontext wird in den Ausführungskontextstapel verschoben

ECStack = [ globalContext ];

Initialisieren Sie den globalen Kontext

globalContext = {
    VO: {
        func: reference to function func(){},
        getValue: reference to function getValue(){}
    },
    Scope: [globalContext.VO],
    this: globalContext.VO //全局上下文
}

Initialisieren Sie den globalen Kontext und erstellen Sie zwei Funktionen gleichzeitig Gleichzeitig werden sie auch gespeichert. Ihre übergeordnete Bereichskette liegt innerhalb ihrer internen Eigenschaften [[Bereich]]

func.[[scope]] = [
     globalContext.VO
];
getValue.[[scope]] = [
     globalContext.VO
];

Der Code beginnt zu diesem Zeitpunkt mit der Ausführung. Wenn die letzte Anweisung ausgeführt wird, wird zuerst die Funktion func ausgeführt, die erstellt wird Ein schrittweiser Funktionsausführungskontext:

  • Kopieren Sie das Funktionsattribut [[scope]], um die Bereichskette zu erstellen

  • Erstellen Sie das aktive Objekt mit Argumenten

  • Initialisieren Sie das aktive Objekt

  • Schieben Sie das aktive Objekt an die Spitze der checksfunccope-Bereichskette.

  • Erstellen Sie diese einfache Analyse: Der MemberExpression-Wert ist func, func ist ein Funktionsobjekt, natürlich eine Referenz, deren Basiswert EnvironmentRecord ist, also ist dieser Wert ImplicitThisValue(ref) und der Rückgabewert ist immer undefiniert Im nicht strengen Modus wird sein Wert implizit in ein globales Objekt konvertiert.

funcContext = {
    AO: {
        arguments: { // 数组
            0: 1,
            length: 1
        }
    },
    Scope: [AO, globalContext.VO],
    this: undefined
}

Manche Leute haben vielleicht Fragen, was ist mit getValue in func? Da es keine Variablendeklaration gibt, handelt es sich tatsächlich um eine Attributzuweisungsoperation, die später zur Laufzeit ausgeführt wird.

Erstellen Sie den Funktionsausführungskontext und verschieben Sie ihn in den Ausführungskontextstapel

    ECStack = [
        funcContext,
        globalContext
    ];

Die Funktion beginnt mit der Ausführung. Dies ist der Schlüssel dafür, warum die endgültige Ausgabe 1 ist. Im ersten Satz der Zuweisungsoperation müssen Sie die finden Schauen wir uns dann die Variable getValue im Ausführungskontext an. Zuerst finden wir, dass das Attribut getValue nicht vorhanden ist, und suchen dann nach globalContext.VO Zu diesem Zeitpunkt weisen wir das getValue-Attribut im globalen Bereich neu zu, wodurch der Funktionsbereich neu erstellt und die übergeordnete Bereichskette dieser neuen getValue-Funktion in ihren internen Eigenschaften gespeichert wird. ] Drinnen:

getValue .[[scope]] = [ funcContext.AO, globalContext.VO ];
Dann geben Sie dies weiter zurück, finden Sie dies von funcContext, das heißt, geben Sie undefiniert zurück; der Funktionsausführungskontext wird vom Stapel entfernt

ECStack = [ globalContext ];

Führen Sie weiterhin Func(1).getValue()aus > , die erste Hälfte gibt undefiniert zurück. Zu diesem Zeitpunkt konvertiert das System implizit in ein globales Variablenobjekt und findet das getValue-Attribut aus dem globalen Variablenobjekt. Zu diesem Zeitpunkt stellten wir fest, dass getValue nicht mehr der Junge war, der es damals war. Der Funktionsausführungskontext zum Ausführen des neuen getValue wurde auf den Stapel verschoben:

getValueContext = {
    AO: {
        arguments: { // 数组
            length: 0
        }
    },
    Scope: [ AO, funcContext.AO, globalContext.VO ],
    this: undefined
} ECStack = [
    getValueContext,
    globalContext
 ];

Die Funktion begann mit der Ausführung und stellte fest, dass sie value und suchte danach. Es gibt kein solches Attribut in getValueContext.AO. Suchen Sie weiter nach funcContext.AO (Func(1).getValue(),前半部分返回了 undefined ,此时系统隐式转换为全局变量对象,从全局变量对象中找到 getValue 属性。这时候我们发现 getValue 早已不是当年那个少年,执行全新的 getValue 的函数执行上下文并入栈:

rrreee

函数开始执行,发现她要输出 valueAchtung!). , der entsprechende Wert wird ausgegeben und 1 wird ausgegeben.

Die Funktionsausführung ist abgeschlossen, getValueContext und globalContext werden vom Stapel entfernt und nacheinander zerstört, und der Code ist abgeschlossen.

Zusammenfassung

Dieser Film verwendet ein einfaches, aber nicht einfaches Beispiel, um die vorherigen vier Artikel zu verbinden und den Arbeitsprozess des Ausführungskontexts bei der Ausführung von JS-Code vollständig zu analysieren . Ich frage mich jedoch, ob aufmerksame Schüler entdeckt haben, dass im obigen Beispiel während der Ausführung der getValue-Funktion ab dem Schritt des Ermittelns des Attributwerts (Markieren der Position) zu diesem Zeitpunkt offensichtlich die Funktion func ausgeführt wurde Sein Ausführungskontext wurde freigegeben. Warum können wir das Wertattribut immer noch aus seinem Ausführungskontext finden? Dies ist eigentlich das Prinzip der Verschlussgenerierung. Im nächsten Artikel werden wir dieses Beispiel noch verwenden, um das Prinzip der Verschlussgenerierung zu lernen.

【Empfohlenes Lernen:

Javascript-Tutorial für Fortgeschrittene

Das obige ist der detaillierte Inhalt vonEin Artikel über den Ausführungskontext in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen