JS-コンテキストの実行


このサイト.

実行コンテキストとは?

  • JSにはscope、hill、this、function、closureなどの動作原理の核心が含まれている.
  • 1.実行コンテキストのタイプ


    1.1 Global Execution Context

  • グローバル実行コンテキスト
  • 基本的な実行コンテキストを示す
  • 関数内部コードでないすべてのコードが対応
  • グローバルオブジェクトを作成してグローバルオブジェクトにバインド
  • 一つしか存在しない
  • 1.2 Functional Execution Context

  • 実行関数のコンテキスト
  • 関数を呼び出すたびに、新しい実行コンテキスト
  • が生成されます.
  • 複数存在可能
  • 1.3 Eval Function Execution Context


    通常、Eval関数の内部コードのコンテキストとしては使用されません.

    2. Execution Stack


    呼び出しスタックと呼ばれ、スタック構造から構成されています.JSでは,実行コンテキストをスタック構造で管理する.
    let a = 'Hello World!';
    function first() {
      console.log('Inside first function');
      second();
      console.log('Again inside first function');
    }
    function second() {
      console.log('Inside second function');
    }
    first();
    console.log('Inside Global Execution Context');
  • グローバルコードを実行すると、グローバル実行コンテキストが作成され、スタックにスタックされます.
  • 関数を呼び出すと、その関数のコンテキストが作成され、スタックにスタックされます.
  • 関数が終了すると、関数実行コンテキストが破棄され、実行コントロールが前のコンテキストに戻されます.
  • 3.コンテキストを実行するプロセス


    実行コンテキストは、生成と実行の2つのフェーズを経験します.

    3.1実行コンテキストの作成


    作成フェーズでは、次の2つの構成部品が作成されます.
  • LexicalEnvironment
  • 可変環境
  • ExecutionContext = {
      LexicalEnvironment = <ref. to LexicalEnvironment in memory>,
      VariableEnvironment = <ref. to VariableEnvironment in  memory>,
    }

    3.1.1ディレクトリ環境


    Lexical環境とは、ECMAScript 코드lexical nesting structureに基づいて特定の変数と関数の接続を定義する構造を指す.
    簡単に言えば、識別子と変数のマッピングを担当します.
    var a = 20;
    var b = 40;
    function foo() {
      console.log('bar');
    }
    上記のコードを例として、以下のようにLexical環境を表すことができます.
    lexicalEnvironment = {
      a: 20,
      b: 40,
      foo: <ref. to foo function>
    }
    Lexical環境には、次の3つのコンポーネントがあります.
    Environment Record
    変数と関数宣言のスペースをLexical環境に格納します.ERには2種類あります.
  • Declarative environment record
    変数と関数宣言のスペースを格納します.関数コードのディレクトリ環境には、これらのコードが含まれます.
  • Object environment record
    グローバルコードのLexical環境にはそれが含まれています.変数と関数の直線セグメントに加えて、Object ERにはグローバルオブジェクトも含まれます.
  • ERには、以下に示すように、argumentsというオブジェクトが含まれていることに注意してください.
    function foo(a, b) {
      var c = a + b;
    }
    foo(2, 3);
    
    // argument object
    Arguments: {0: 2, 1: 3, length: 2},
    Outer Environment Reference
    ES 3が正式に使用する用語はScope Chainであり、ES 5は用語を変更し始めた.
    関数がオーバーラップしている場合、サブ関数から親関数までを探索します.グローバル実行コンテキストでもナビゲーションに失敗すると、リファレンスエラーが発生します.
    出典:https://poiemaweb.com/js-execution-context
    This Binding
    以前の位置づけで述べたように

    3.1.2変数環境


    ES 6ではディレクトリ環境と変数環境の違いは1つしかない.Lexical環境は、関数およびlet/const変数バインドに関する情報を格納し、変数環境はvar変数バインドに関する情報のみを格納する.

    3.2実行コンテキストの実行


    コンテキスト作成フェーズで、すべての変数を割り当てた後、実行フェーズに入ります.
    次の例に従います.
    let a = 20;
    const b = 30;
    var c;
    function multiply(e, f) {
     var g = 20;
     return e * f * g;
    }
    c = multiply(20, 30);
    上のコードが実行されると、JSエンジンはグローバル実行コンテキストを生成してグローバルコードを実行します.生成されたコンテキストは次のとおりです.
    GlobalExectionContext = {
      // 렉시컬 환경
      LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          // 전역 변수인 a, b 저장
          // 전역 함수인 multiply 저장
          a: < uninitialized >,
          b: < uninitialized >,
          multiply: < func >
        }
        outer: <null>,
        ThisBinding: <Global Object>
      },
      VariableEnvironment: {
        // 변수 환경
        EnvironmentRecord: {
          Type: "Object",
          // var 형 변수인  c는 변수 환경에 저장된다.
          c: undefined,
        }
        outer: <null>,
        ThisBinding: <Global Object>
      }
    }
    // let과 const로 선언된 변수는 초기화되지 않은 상태로 할당되고,
    //var로 선언된 변수는 기본값(undefined)가 할당되어 있다.
    //이는 호이스팅과 관련이 되어 있다.
    //이러한 동작 이유로 var은 선언되기 전에 참조할 수 있지만,
    //let과 const는 불가능하다(참조 에러)
    実行フェーズに入ると、すべての変数が割り当てられます.
    GlobalExectionContext = {
    LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          // 전역 변수 값이 할당된다.
          a: 20,
          b: 30,
          multiply: < func >
        }
        outer: <null>,
        ThisBinding: <Global Object>
      },
    VariableEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          c: undefined,
        }
        outer: <null>,
        ThisBinding: <Global Object>
      }
    }
    これで、multiply関数に遭遇すると、新しい関数実行コンテキストが作成され、スタックにスタックされます.
    FunctionExectionContext = {
    LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Declarative",
          // argument 객체에 저장된다.
          Arguments: {0: 20, 1: 30, length: 2},
        },
      	//상위 컨텍스트를 가리키는 outer
        outer: <GlobalLexicalEnvironment>,
        ThisBinding: <Global Object or undefined>,
      },
    VariableEnvironment: {
        EnvironmentRecord: {
          Type: "Declarative",
          // Identifier bindings go here
          g: undefined
        },
        outer: <GlobalLexicalEnvironment>,
        ThisBinding: <Global Object or undefined>
      }
    }
    その後、実施段階に入る.(関数実行コンテキスト内のすべての変数の割り当てが完了しました)
    ここで少し混同される可能性があるのは、すでに実行段階に入っていると考えられる点です.各実行コンテキストには、同じ作成および実行手順があります.したがって、前のグローバル実行コンテキストにも実行ステップがあり、現在の関数実行コンテキストにも実行ステップがあります.
    FunctionExectionContext = {
    LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Declarative",
          Arguments: {0: 20, 1: 30, length: 2},
        },
        outer: <GlobalLexicalEnvironment>,
        ThisBinding: <Global Object or undefined>,
      },
    VariableEnvironment: {
        EnvironmentRecord: {
          Type: "Declarative",
          g: 20
        },
        outer: <GlobalLexicalEnvironment>,
        ThisBinding: <Global Object or undefined>
      }
    }
    関数の実行が完了すると、returnの値がcに格納されます.グローバルLexical環境に更新されます.グローバルコードが完了すると、プログラムは終了します.