JavaScriptを深く追究する——実行文脈

3675 ワード

定義
実行コンテキスト(実行環境execution contextとも呼ばれる)(略称:EC)は抽象的な概念で、関数が呼び出された時に、関数が本当に実行される前に作成されたものです.各実行文脈には変数オブジェクトがあり、現在の環境にあるすべての変数または関数宣言またはモダリティアーグメンントおよびthisが保存されています.
一連の活動の実行文脈は論理的にスタックを形成する.スタックの底は常にグローバルコンテキストであり、スタックの一番上は現在(アクティブ)の実行コンテキストである.フローエントリ関数を実行すると、関数の環境が一つの環境スタックに押し込まれ、関数が実行された後、スタックはその環境をイジェクトし、制御権を前の実行環境に戻す._; コードは環境で実行され、変数オブジェクトの作用ドメインチェーンを作成し、作用ドメインチェーンは実行の順序を保証します.
三つの運転環境
  • グローバル:
  •   は一つの大域の文脈だけが存在し、この文脈は他の任意の文脈によってアクセスできる.
  • 関数:
  • 関数を実行するたびにエンジンが自動的に関数実行コンテキストを作成します.ローカルスコープを新たに作成します.プライベート変数などは、外部のコンテキストでは直接にアクセスできません.全体コンテキストで関数の実行を呼び出すと、プログラムフローは呼び出された関数の中に入ります.このとき、エンジンはこの関数のために新しい実行コンテキストを作成します.ブラウザは、常にスタックの上部にある現在のコンテキストを実行し、実行が終了すると、そのコンテキストはスタックの上部からポップアップされ、その後、最新のスタックの上部のコンテキスト実行コードに入ります.スタック内のコンテキストは、グローバルコンテキストに戻るまで、順次実行され、スタックをポップアップする.
  • eval関数
  • _; がeval関数内で実行するコードです.
    コンテキストの確立、実行プロセスを実行します.
    確立段階:
    関数を呼び出したときに発生しますが、関数の具体的なコードを実行する前に発生します.
    variaboleObjectオブジェクトを作成します.
    まずargmentsパラメータを処理し、次に関数の宣言を行い、最後に変数の宣言を行います.
      は、アーグメンントオブジェクトを作成し、現在のコンテキストのパラメータを確認し、そのオブジェクトの属性と属性値を設定します.各実行環境には、関連する変数オブジェクトがあり、環境で定義されているすべての変数と関数がこのオブジェクトに保存されます.私たちが作成したコードはこのオブジェクトにアクセスできませんでしたが、解析器はデータを処理する際にバックグラウンドで使います.
    関数宣言の関数名を見つけて、variable Objectの下にこの関数名で属性を作成します.属性値はこの関数のメモリ内のアドレスを指す参照です.上記の関数名が既にvariable Objectの下に存在する場合、対応する属性値は新たな参照によってカバーされます.
    現在のコンテキストの変数宣言を確認します.変数を発見するごとに声明はvariable Objectの下で変数名で属性を作成します.属性値はundefinedです.この変数名が既にvariable Object属性に存在する場合、直接スキップ(関数に対する属性の値が変数属性によってundefinedに上書きされるのを防ぐ)します.元の属性値は変更されません.
    初期化スコープ
      それぞれの関数は自分の実行環境を持っています.実行ストリームが関数に入ると、関数の環境が環境スタックに押し込まれます.関数が実行された後、スタックはその環境をイジェクトし、制御権を前の実行環境に戻す.ECMAScriptプログラムの実行フローはこの便利なメカニズムによって制御されています.コードが環境で実行されると、変数オブジェクトのスコープチェーンが作成されます.作用するドメインチェーンの用途は、実行環境にアクセスできるすべての変数と関数に対する規則的なアクセスを保証することである.スコープの先端は、常に現在実行されているコードのある環境の変数オブジェクトです.この環境が関数である場合、その活動対象を変数オブジェクトとします.活動対象は最初に一つの変数だけを含んでいます.つまり、argmentsオブジェクト(このオブジェクトはグローバル環境には存在しません.)フィールドチェーンの次の変数オブジェクトは、含まれる環境から来ます.次の変数オブジェクトは次の環境から来ます.このようにして、グローバル実行環境に至るまで継続します.グローバル実行環境の変数オブジェクトは常にフィールドチェーンの最後のオブジェクトです.
    コンテキストでthisのオブジェクトを指定します.
      はwindowまたは現在のオブジェクトを指すことを確定します.
    コード実行フェーズ
  • は、バリアフリーObject内の変数に
  • を与えます.
    function aoo(i){
        var a = 'staven';
        var b = function boo(){
            
        };
        function coo(){
            
        }
    }
    aoo(1);
  • は、aooを呼び出し(1)、段階を作って上記のオブジェクトを実行する:
  • aooExecutionContext = {
        variableObject:{
            arguments:{
                0:1,
                length:1
            },
            i:1,
            coo:(  function coo()),
            a:undefined,
            b:undefined
        },
        scopeChain:{……},
        this:{……}
    };
  • 実行フェーズ、実行コンテキストオブジェクト:
  • aooExecutionContext = {
        variableObject:{
            arguments:{
                0:1,
                length:1
            },
            i:1,
            coo:(  function coo()),
            a:"staven",
            b:(  function boo())
        },
        scopeChain:{……},
        this:{……}
    };
    解析変数の昇格
    (function(){
        console.log(typeof foo);  //function
        console.log(typeof bar); //undefined
        
        var foo = 'hello',
            bar = function(){
                return "staven";
            };
        function foo(){
            return "hello";
        }
        console.log(typeof foo); //string
        console.log(typeof bar); //function
    }());
      は文脈の確立段階で、まずargmentsを処理して、パラメーター、続いて関数の声明で、最後に変数の声明です.foo関数の声明が見つかったら、variaboleObjectの下にfoo属性を作成します.その値は指向関数の参照です.変数宣言を処理すると、var fooの声明がありますが、variable Objectはすでにfoo属性を持っていますので、直接スキップします.コード実行段階に入ると、foo属性にアクセスできます.既に存在し、関数参照です.  barは変数の宣言で、段階を創立する時、与えられたデフォルトの値はundefinedです.コード実行段階で特定の値が与えられるので、typeof(bar)を呼び出したときに出力される値はundefinedです.
    󯌬☜☜☜☜☜☜☜☜