JavaScriptはコンテキストの作用領域チェーンを実行します.

2492 ワード

JavaScriptの各関数は、実行中に実行コンテキスト(execution context)を作成し、実行コンテキストオブジェクトには以下の属性が格納されています.
  • 変数オブジェクト
  • 作用ドメインチェーン
  • this
  • スコープチェーン
    セクションで実行されているコードが変数を検索すると、現在のコンテキストの変数オブジェクトから先に検索されます.見つけられない場合、親レベル(語法レベルの親レベル)からコンテキストの変数オブジェクトを検索して、大域コンテキストの変数オブジェクト、すなわちグローバルオブジェクトを探します.このように、複数のコンテキストを実行する変数オブジェクトからなるリンクは、スコープチェーンと呼ばれます.
    関数の作成
    JavaScriptは静的作用領域を使用するので、関数の作用領域は関数定義時に決定された.各関数オブジェクトは内部属性を持っています.関数が作成されると、すべての親レベルの変数オブジェクトが保存されます.なお、この場合の[Scrope]属性に保存されているのは、完全な作用ドメインチェーンではない.以下は一例です.
    function foo() {
        function bar() {
            ...
        }
    }
    
    関数の作成時、それぞれの[scope]属性は以下の通りです.
    foo.[[scope]] = [
      globalContext.VO
    ];
    
    bar.[[scope]] = [
        fooContext.AO,
        globalContext.VO
    ];
    
    関数の有効化
    関数コンテキストに入ると、VO/AOを作成すると、アクティブなオブジェクトをチェーンの先端に追加します.このとき関数コンテキストに保存されているスコープは最終的に完全なスコープチェーンです.
    Scope = [AO].concat([[Scope]]);
    
    締め括りをつける
    以下のコードを例にとって、関数がコンテキストで作用するドメインチェーンと変数オブジェクトの作成過程をまとめます.
    var scope = "global scope";
    function checkscope(){
        var scope2 = 'local scope';
        return scope2;
    }
    checkscope();
    
  • checkscope関数が作成され、作用ドメインチェーンが内部属性[scope]
  • に保存されます.
    checkscope.[[scope]] = [
        globalContext.VO
    ];
    
  • はcheckscope関数を実行して、checkscope関数を作成してコンテキストを実行して、checkscope関数の実行コンテキストは実行コンテキストスタック
  • に押し入れられます.
    ECStack = [
        checkscopeContext,
        globalContext
    ];
    
  • checkscope関数はすぐに実行されず、準備作業を開始します.第一歩:コピー関数[scope]属性は、スコープ
  • を作成します.
    checkscopeContext = {
        Scope: checkscope.[[scope]],
    }
    
  • 第二のステップ:argmentsで活動対象を作成し、その後活動対象を初期化し、参加型、関数宣言、変数宣言
  • を追加する.
    checkscopeContext = {
        AO: {
            arguments: {
                length: 0
            },
            scope2: undefined
        },
        Scope: checkscope.[[scope]],
    }
    
  • 第3ステップ:活動対象をcheckscope作用ドメインチェーンのトップ
  • に押し込む.
    checkscopeContext = {
        AO: {
            arguments: {
                length: 0
            },
            scope2: undefined
        },
        Scope: [AO, [[Scope]]]
    }
    
  • 準備作業が完了し、実行関数が実行されるにつれて、AOの属性値
  • が変更されます.
    checkscopeContext = {
        AO: {
            arguments: {
                length: 0
            },
            scope2: 'local scope'
        },
        Scope: [AO, [[Scope]]]
    }
    
  • は、scope 2の値を検索し、バック関数の実行が完了し、関数コンテキストが実行コンテキストスタックから
  • をイジェクトする.
    ECStack = [
        globalContext
    ];
    
    参考文献
  • https://github.com/mqyqingfeng/Blog/issues/6