JavaScriptはコンテキスト変数オブジェクトおよび変数、関数宣言を実行しますが、なぜ事前に

12187 ワード

前のブログでは、「JavaScriptの演算、バイナリ浮動小数点の丸め誤差と比較、類型転換と変数宣言の早期問題について」に言及しましたが、関数、変数声明は前倒ししていますが、なぜ説明されていませんでしたか?本文では、コンテキストと変数オブジェクトの両方の観点から、なぜ関数、変数の申明が事前に行われるのかを話します.
_;  は実行文脈と変数対象について、個人的にはオンラインでいくつかの優れた博文があると思います._; 1)はJavaScriptシリーズを深く理解します.(11):実行文脈(Execution Cotexts)は、JavaScriptシリーズを深く理解します.専門用語を比較して理解しやすいです.前の段階(二):文脈の詳細な図解を実行し、前の段階(三):変数の対象の詳細は、個人的にはよく書けていると思います.読者の友達は、実行コンテキストと変数のオブジェクトを深く理解したいなら、この2つのブログを読んでください.
1、実行コンテキスト
コントローラがECMAScript実行可能なコードに移るたびに、実行コンテキストに入ります.実行コンテキストは現在のコードの実行環境として理解できます.JavaScript実行環境は大体3つの状況を含みます.
  • グローバル環境:JavaScriptコードが実行されると、まずこの環境に入ります.例えば、外部のjsファイルまたはラベル内のコードをロードします.
  • 関数環境:関数を呼び出して実行すると、現在の関数でコードが実行されます.
  • eval(使用を推奨せず、無視できる)
  • したがって、JavaScriptコードの実行中に、必ず複数の実行コンテキストが発生します.JavaScriptエンジンはスタックの方式でそれらを処理します.ECStock=[]で表してもいいです.まずグローバルコンテキストに押し入れられます.関数のコンテキストを終了して、スタックの一番上のECStockからポップアップし、ページまたはブラウザが閉じるまでグローバルコンテキストは常に存在します.
    2、変数オブジェクト
    実行コンテキストにはライフサイクルがあります.作成段階とコード実行段階です.
  • 作成段階:この段階では、実行文脈はそれぞれ変数オブジェクトを作成し、スコープチェーンを確立し、thisの指向を決定します.変数オブジェクトはVOで表されると、VO={argments、function、var変数}に類似するべきです.
  • コードの実行フェーズ:作成が完了すると、コードの実行が開始されます.このとき、変数の割り当て、関数の参照、その他のコードの実行が完了します.
  • DEMOを見てください
    function test() {
        console.log(a);
        console.log(foo());
    
        var a = 1;
        function foo() {
            return 2;
        }
    }
    test();
    
    コードがtest()に実行されるたびに、新しい関数を作成してコンテキストを実行し、ECStock[globalEC,testEC]に押し込んで、testECは2つの段階があり、疑似コードは以下の通りである.
    //     
    testEC = {
        VO: {},		//     
        scopeChain: {},
          this  
    }
    VO = {
        arguments: {...}, 
        foo: <foo reference>  //   foo     
        a: undefined
    }
    
    //     
    VO ->  AO   // VO   , AO  ,Active Object
    AO['a'] = 1
    ```js
    
      demo  ,  :
    ```js
    function test() {
        function foo() {		//           
            return 2;
        }
    	var a;
        console.log(a);
        console.log(foo());
        a = 1;
    }
    test();
    
    ここで、なぜ変数、関数宣言が前倒しされたのかが分かりました.まとめてみます.2つの文があります.1)実行文脈は2つの段階があり、作成段階(コンテキストに入る)、実行段階があります.2)作成段階では変数オブジェクトが作成されます.変数オブジェクトには以下の属性が含まれます.
  • 関数のすべてのモダリティ(関数実行コンテキストの場合)、argments
  • すべての関数宣言
  • すべての変数宣言
  • 3、関数宣言の優先度が変数宣言より高い
    同様に事前に宣言されていますが、関数宣言の優先度は変数宣言より高く、関数宣言が先に実行されます.変数名(同名関数が既に宣言されている)が上書きされない場合、変数は先に定義されていますが、その後の割当値は関数宣言を上書きします.古典的なデモを見てください.
    	alert(x); 		// function x() {}
    	var x = 10;
    	alert(x); 		// 10
    	x = 20;
    	function x() {};
    	alert(x); 		// 20
    
    コンテキスト、変数オブジェクトを結合すると、コードは同じです.
    	function x() {};
    	alert(x); 		// function x() {}
    	x = 10;
    	alert(x); 		// 10
    	x = 20;
    	alert(x); 		// 20
    
    関数宣言ではなく、関数表現ですか?
    	console.log(x); 		// undefined
    	var x = 10;
    	console.log(x); 		// 10
    	x = 20;
    	var x = function() {};
    	console.log(x); 		// function x() {}
    
    関数式、変数定義と同等で、コードの順序によって実行されます.上記のコードは同じです.
    	var x;
    	console.log(x); 		// undefined
    	x = 10;
    	console.log(x); 		// 10
    	x = 20;
    	x = function() {};
    	console.log(x); 		// function x() {}