[Javascript]実行コンテキストとは?(Execution Context)


このロケーションでは、JavaScriptの実行コンテキスト、エスケープ、エスケープに関する作業をまとめます.
(このプレゼンテーションは、コアJavaScriptの書籍に基づいています.)

1.コンテキストを実行しますか?


実行コンテキスト(Execution Context)は、実行するコードの環境情報を含むオブジェクトです.
JavaScriptはコードを実行し、必要な環境情報(ex.変数、関数など...)を提供します.これらの作成実行コンテキストを使用して、呼び出しスタックにスタックし、最上位のコンテキストに関連するコードを実行して、コード全体の環境と順序を確保します.

1.1実行コンテキストの作成時


「同じ環境」、つまり、次のように実行コンテキストを構成できます.
1.グローバルスペース(JavaScript起動時)
2.eval()関数
3.関数実行時
自動的に生成されるグローバル空間と悪魔と見なされるeval(悪魔と見なされる理由)を除いて,実行コンテキストを構築する方法は実行関数のみであることが多い.(宣言された時点ではなく、関数を実行(呼び出す)時点です.)

1.2コンテキストとコードの実行プロセスを実行する

// ---------------- (1)
var a = 1;
function outer() {
	function inner() {
    	console.log(a) // undefined
        var a = 3;
    }
    inner() // ---------------- (2)
    console.log(a) // 1
}
outer() // ---------------- (3)
console.log(a) // 1
  • (1)にグローバルコンテキストを作成し、コールスタックにスタックします.(グローバルコンテキストの概念は一般的な実行コンテキストとあまり変わりません.ただし、コードに個別の実行コマンドがなくてもブラウザで自動的に実行されるため、JavaScriptファイルが開くとグローバルコンテキストがアクティブになることは理解できます.)
  • は、コード(3)を再実行し、outer()を呼び出し、outer()関数を実行する実行コンテキストを生成し、呼び出しスタックにスタックする.
    外部実行コンテキストは呼び出しスタックの上部にあるため、グローバルコンテキストに関連するコードの実行を一時停止し、外部実行コンテキストに関連するコード、すなわち外部関数内部のコードを順次実行します.
  • outer()関数実行、コード実行、(2)inner()関数を呼び出し、inner()関数の実行コンテキストを作成し、呼び出し構造に積み上げます.
  • カーネル()関数でaをコンソールに出力すると、カーネル()は実行するコードがないためcallスタックから削除されます.
  • 次の呼び出しスタックの上部にあるouter()関数は、(2)の下にあるコンソールで再実行されます.ログ(a)が実行され、aがコンソールに出力されます.
    outer()関数も呼び出しスタックから削除されます.
  • 呼び出しスタックの上部にあるグローバルコンテキストが再実行され、最後の行は再びaをコンソールに出力して終了します.
  • 2.実行コンテキストの構成


    実行コンテキストオブジェクトには、次の情報が含まれます.
  • VariableEnvironment:現在のコンテキスト内の識別子に関する情報+外部環境情報.リリース時のLexicalEnvironmentスナップショットは、変更を反映しません.
  • environmentRecord
  • outer-EnvironmentReference
  • LexicalEnvironment:最初はVariableEnvironmentと同じでしたが、変更をリアルタイムで反映
  • environmentRecord
  • outer-EnvironmentReference
  • ThisBinding:この識別子が表示されているターゲットオブジェクト
  • VariableEnvironmentにはLexicalEnvironmentと同じ内容が含まれていますが、初期実行時のスナップショットが保持されている点が異なります.コンテキストを実行するときは、まずVariableEnvironmentに情報を含め、それをコピーしてLexicalEnvironmentを作成し、主にLexicalEnvironmentとを使用します.通常、関数のLexicalEnvironmentは、その関数が持つローカルスキャン範囲を表します.
    この2つの環境の内部は、EnvironmentRecordとOuterEnvironmentReferenceに再編成されています.

    EnvironmentRecord:コンテキストに関連するコードの識別子情報を格納する
    OuterEnvironmentReference:関数宣言を呼び出すときのメキシコ環境へのポインタで、スキャンチェーンを可能にします.

    3.EnvironmentRecordの構成


    EnvironmentRecordは、現在のコンテキストに関連するコードの識別子情報を格納します.
    var a = 3; // 여기서 식별자는 a를 말합니다. 
    コンテキスト全体で識別子を順番に収集します.ここで収集された識別子には、パラメータ識別子、宣言された関数、およびvarとして宣言された変数の識別子が含まれます.
    function foo(x) {
      console.log(x);
      var a = 1;
      var b = 2;
      function boo() {
      console.log("work")
      }
    }
    foo(1)
    上記のコードでは、コンテキストのEnvironmentRecordを実行すると、識別子x、a、b、および関数fooが収集されます.EnvironmentRecordは、現在実行中のコンテキストターゲットコードの識別子を最初に収集するため、変数の識別時に識別子のみをドラッグ&ドロップし、割り当てプロセスは元の場所に順番に保持されます.
    「JavaScriptエンジンは、コードが実行される前にも、その環境内のすべてのコード変数名を知っています」=>「昇格」の概念です.
    function a (x) {
      var x; // 매개변수를 변수 선언/할당과 같다고 가정하고 변환하면...
      var a;
      var b;
      function foo() {
        console.log('work');
      };
      
      x = 1;
      console.log(x);
      a = 1;
      b = 2;
    }
    
    a(1);
    上記のコードのように、識別子を収集してから順番にコードを実行する例は、コード作成を説明する際によくある例です.

    4.スキャン、スキャンチェーン、OuterEnvironmentReference


    OuterEnvironmentReferenceを理解するには、まずScopeの概念を理解する必要があります.スコットランド、識別子の有効範囲.JavaScriptには、グローバルスコープ(global scope)とエリアスコープ(local scope)が含まれます.
    var a = 1;
    function scope() {  // 함수 스코프
      var b = 2;
      console.log(a);  // 1
      console.log(b);  // 2
    }
    console.log(a);  // 1
    console.log(b);  // b is not defined
    scope関数以外で宣言された変数aは、関数scope内でもアクセス可能であるが、関数内で宣言された変数bは、関数内でのみアクセス可能である.変数aはグローバル範囲内であるため、変数bは領域範囲内である.
    JavaScriptは、変数の有効範囲を検索するときに、範囲チェーン(scope chain)と呼ばれる内側から外側に検索します.
    したがって、グローバル範囲に宣言された変数は、任意の場所からアクセスできます.逆に、ゾーンスキャンは宣言された関数にのみアクセスできます.
    OuterEnvironmentReferenceは、現在の呼び出し関数宣言時のLexicalEnvironmentへのポインタです.OuterEnvironmentReferenceは接続リストの形式を表示し、「宣言時のLexicalEnvironment」の検索を続行します.宣言ポイントのLexicalEnvironmentは、最終的にこの関数が属する親scopeの範囲です.
    各関数のOuterEnvironmentReferenceは、宣言時のLexicalEnvironmentのみを参照するため、最近の要素から上へ順にアクセスできます.
    var a = 1;
    
    var outer = function () {
      var inner = function () {
        console.log(a); // undefined 출력 (a가 LexicalEnvironment에서 발견되지만, 값이 할당되기 전)
        var a = 3;
      };
      
      inner();
      console.log(a); // 1 출력 (outerEnvironmentReference에서 발견한 값 출력)
    };
    
    outer();
    console.log(a); // 1 출력 (LexicalEnvironment에서 발견한 값 출력)
    グローバルコンテキスト
  • 環境レコード:{a,outer}識別子
  • を格納
  • 外部環境リファレンス:何も含まれていません
  • 外部実行コンテキスト
  • 環境レコード:{内部}識別子
  • を格納
  • グローバルに宣言されているため、レプリケーショングローバルコンテキストのLexicalEnvironment参照
  • 外部環境参照:[GLOBAL,{a,outer}]タグ
  • 最初は実行コンテキスト名、2番目は環境記録オブジェクト
  • である.
    内部実行コンテキスト
  • 環境レコード:{a}識別子
  • を保存
  • outer関数で宣言されているため、外部関数のLexicalEnvironmentリファレンスコピー
  • outerEnvironmentReference : [ outer, { inner } ]
  • 5. ThisBinding


    実行コンテキストでは、this Bindingはthisによって指定されたオブジェクトを格納します.コンテキストの開始時にthisが指定されていない場合、thisはグローバルオブジェクトを格納します.また、ここに格納されているターゲットは、関数を呼び出す方法によって異なります.これについては後で話しましょう.『this』を深く掘り下げるつもりだ

    6.整理


    javascriptでは、実行コンテキストは、実行コードに必要な情報の範囲をオブジェクトとして表します.実行コンテキストを構成するLexicalEnvironmentには、現在の実行コンテキストを実行するための複数の情報が含まれています.LexicalEnvironmentは、識別者情報を含むEnvironmentRecordと、参照親LexicalEnvironmentがスキャンチェーンを可能にするOuterEnvironmentReference情報からなる.EnvironmentRecordは識別子バインディングを管理し、バインディングオブジェクトとして宣言された特定のオブジェクト属性の識別子を管理します.OuterEnvironmentReferenceは、宣言時に現在の実行コンテキストを構成する関数が存在する親LexicalEnvironmentを参照するため、識別子の有効範囲を親に遡って検索できます.