[23章]実行コンテキスト


23.1ソースタイプ


ECMAScript仕様では、ソースコードを4種類に分類します.4種類のソースコード生成実行コンテキスト.
1)グローバルコード
グローバルコードは、グローバルスキャンを生成する必要があります.varキーワードとして宣言されたグローバル変数と、関数として定義されたグローバル関数をグローバルオブジェクトのpropertyとメソッドにバインドし、グローバルオブジェクトに関連付けて参照する必要があります.
2)関数コード
関数コードは、ゾーンスキャンを生成し、ゾーン変数、パラメータ、パラメータオブジェクトを管理する必要があります.生成された領域スキャンは、スキャンチェーンに接続する必要があります.
3)evalコード
evalコードはstrictモードで独自の独立したスキャンを生成する.
4)モジュールコード
モジュールコードは、各モジュールに対して独立したモジュールスキャンを生成します.

23.2ソースコードの評価と実行


JavaScriptエンジンは、ソースコードを「評価」と「実行」の2つのプロセスに分けて処理します.
評価の過程で、実行コンテキストが作成され、変数や関数などの宣言を先に実行することによって生成された変数または関数識別子が、実行コンテキストによって管理されるscopeに鍵として登録されます.
実行プロセス(実行時)では、変数または関数の参照は実行コンテキストによって管理され、スキャンによって取得されます.ソースコードの実行結果(その後の変数値の変更など)は、コンテキスト管理を実行するscopeに再登録されます.

23.3コンテキストを実行する役割


実行コンテキストは、識別子(変数、関数、クラスなどの名前)とコード実行順序管理を登録および管理する内部メカニズムであり、すべてのコードは実行コンテキストによって実行および管理されます.
識別子とタグは、実行コンテキストのディレクトリ環境によって管理され、コードの実行順序は実行コンテキストスタックによって管理されます.

23.4コンテキストスタックの実行


1)JavaScriptエンジンはまずグローバルコードを評価し,グローバル実行コンテキストを生成する.関数を呼び出すと、関数コードが評価され、関数実行コンテキストが生成されます.
2)
const x = 1;
function foo() {
  const y = 2;  
  function bar() { 
    const z = 3;
    console.log(x + y + z);
  }
  bar();
}
foo();

3)実行コンテキストスタック上部の実行コンテキストは、常に現在実行されているコードの実行コンテキストである.これを実行中の実行コンテキスト(running execution context)と呼びます.

23.5ローカル環境


1)Lexical環境は,識別子と識別子のバインディング値,および位相スキャンの参照を記録する資料構造である.コンテキストセット環境管理scopeと識別子を実行します.
2)リモート環境は環境記録(Environment Record)と外部リモート環境リファレンス(Outer LexicalEnvironment Reference)からなる.
3)環境記録は、記録中の識別子を登録し、登録識別子にバインドされた値を管理するためのリポジトリである.
4)外部Lexical環境への参照は親スキャンである.外部集合環境の参照により,走査チェーンを実現した.

23.6コンテキストの作成と識別子検索プロセスの実行


1)グローバルオブジェクトの作成
グローバル・オブジェクトは、グローバル・コードを評価する前に生成されます.グローバルオブジェクトには、構築されたグローバルプロパティ、構築されたグローバル関数、および標準的に構築されたオブジェクトが含まれ、動作環境に応じてホストオブジェクトまたはクライアントWeb APIも含まれます.Object.原型を継承する原型チェーンの一員です.
2)グローバルコード評価
グローバルコード評価プロセス
1. 전역 실행 컨텍스트 생성
2. 전역 렉시컬 환경 생성
   2.1. 전역 환경 레코드 생성
        2.1.1 객체 환경 레코드 생성
        2.1.2 선언적 환경 레코드 생성
   2.2 this 바인딩
   2.3 외부 렉시컬 환경에 대한 참조 결정

  • グローバル実行コンテキストの作成
    空のグローバル実行コンテキストを生成し、実行コンテキストスタックにプッシュします.


  • グローバルコレクション環境の作成
    2.1. グローバル環境レコードの作成
    グローバル環境レコードは、グローバル変数を管理するグローバル範囲、グローバルオブジェクトとしてのコンストラクタのグローバル範囲、コンストラクタとしてのグローバル関数、および標準コンストラクタとしてのオブジェクトを提供します.
    letまたはconstに示すように、すべてのグローバル変数がグローバルオブジェクトのpropertyであるわけではありません.したがって,let,const,varを区別して管理するために,グローバル環境記録はオブジェクト環境記録と宣言環境記録に分けられる.
    varキーワードとして宣言されたグローバル変数と、関数として宣言されたグローバル関数、構築されたグローバルproperty、構築されたグローバル関数、標準構築されたオブジェクトは、オブジェクト環境レコードによって管理され、let、contキーワードとして宣言されたグローバル変数は、宣言環境レコードによって管理されます.
    2.1.1オブジェクト環境記録の作成
    オブジェクト環境レコードはBindingObjectと呼ばれる「グローバルオブジェクト」に関連付けられています.
    グローバルコード評価の過程で、varキーワードとして宣言されたグローバル変数と、関数として定義されたグローバル関数は、グローバル環境記録に接続されたオブジェクト環境記録のBindingObjectを介してグローバルオブジェクトのpropertyとメソッドとなる.
    このプロセスにより、varキーワードとして宣言されたグローバル変数と、関数宣言文として定義されたグローバル関数は、グローバルオブジェクトの識別子(ウィンドウ)を指さすことなく、オブジェクトのpropertyを参照できます.

    2.1.2宣言環境記録の作成
    letは、constキーワードを使用して宣言されたグローバル変数が登録され、宣言環境レコードに管理されます.

    letはconstキーワードで宣言された変数でも変数反発が発生しますが、実行時にコントロールが変数宣言文に到達する前に一時的な死角地帯に陥るため、参照できません.
    2.2このバインディング
    グローバル環境レコードの[GlobalThisValue]内部スロットにthisをバインドします(これはグローバルコードなのでグローバルオブジェクトです).したがって、グローバルコードで参照すると、グローバル環境レコードの[GlobalThisValue]内部スロットにバインドされているオブジェクトが返されます.
    このバインドは、グローバル環境レコードと関数環境レコードにのみ存在します.グローバル環境レコードを構成するオブジェクト環境レコードと、このバインドがないことを宣言します.

    2.3外部集合環境の参照の決定
    外部レクサス環境への参照とは、親ミラーを指します.親スキャン(グローバルコード)がない場合は、外部コレクション環境の参照にnullが割り当てられます.

  • 3)グローバルコードの実行
    識別子には、スキャンが異なる場合、同じ名前を付けることができます.したがって,どのスペクトルを参照するかを決定する識別子を識別子決定と呼ぶ必要がある.
    識別子を検索すると、実行時コンテキストで識別子の検索が開始されます.宣言された識別子は、実行コンテキストの集合環境の環境レコードに登録されます.
    実行中の実行コンテキストのコレクション環境で識別子を検索できない場合は、外部コレクション環境への参照が指すコレクション環境(親ミラー)に移動して識別子を検索します.現在の位置がスキャンチェーンの終点である場合、参照エラーが発生します.
    4)関数コード評価
    関数コード評価プロセス
    1. 함수 실행 컨텍스트 생성
    2. 함수 렉시컬 환경 생성
       2.1. 함수 환경 레코드 생성
       2.2 this 바인딩
       2.3 외부 렉시컬 환경에 대한 참조 결정
    ほとんどの内容は、「2)グローバルコード評価」で説明した内容と同じです.だから、もっと説明しなければならない部分だけ書きます.
    2.1関数環境レコードの作成
    関数環境は、パラメータ、パラメータオブジェクト、および関数内部で宣言された領域変数とネストされた関数の登録と管理を記録します.
    2.2このバインディング
    関数環境レコードの[ThisValue]内部スロットにバインドされます.[ThisValue]の内部スロットにバインドされているオブジェクトは、関数の呼び出し方法によって異なります.
    JAvascriptは、関数を呼び出すのではなく、どこで定義するかに基づいて、親スキャンを決定します.
    関数定義を評価して関数オブジェクトを作成すると、JavaScriptエンジンは、親スキャンを関数オブジェクトの内部スロット[Environment]に保存します.
    5)関数コードの実行
    コンテンツはグローバルコード実行と同じであるため、これ以上説明しない.

    23.7コンテキストおよびブロックレベルスキャンの実行


    1)varとして宣言された変数は、関数のみを承認するコードブロックが領域スキャンである関数レベルスキャンに従う.
    2)let、constと宣言された変数は、すべてのコードブロック(if文、for文、while文、try/catch文、関数)を領域スキャンと認定するブロックレベルスキャンに従う.
    let x = 1;
    if(true) {
      let x = 10;
      console.log(x); //10
    }
    console.log(x); //1
    クエリーのコード・ブロックを実行する場合は、クエリーのコード・ブロックのブロック・レベル・スキャンを生成する必要があります.このため、既存のグローバルディレクトリ環境を置き換えるために、宣言された環境レコードを持つディレクトリ環境を再作成する必要があります.