ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptのプリコンパイルプロセスを完全にマスターする

JavaScriptのプリコンパイルプロセスを完全にマスターする

WBOY
WBOY転載
2022-02-10 17:57:231871ブラウズ

この記事では、javascript のプリコンパイルに関する関連知識を提供します。主にプリコンパイルの関連問題を例を通して紹介します。皆様のお役に立てれば幸いです。

JavaScriptのプリコンパイルプロセスを完全にマスターする

ステージ (3)

    # 字句解析と構文解析: 字句解析と構文解析では、JavaScript コードに低レベルの構文が含まれているかどうかを確認します。エラー
  1. プリコンパイル: この記事は、
  2. 実行コードに焦点を当てています: 実行コードは、コードを解析する JS エンジンであり、1 行を解析して 1 行を実行します
  3. # #この章では主に
プリコンパイル

プロセスについて説明しますプリコンパイルプロセス

プリコンパイルも2つの時点に分かれています:

    1 つ目は JavaScript コードが実行される前です
  1. 2 つ目は関数が実行される前です。
ただし、JavaScript コードの前では、前のプリコンパイルは 1 回だけ行われ、関数実行前のプリコンパイルは複数回行われます。

1. JavaScript コード実行前のプリコンパイル

JavaScript コードが実行される前に、まずグローバル オブジェクトが作成されます。 window
    object は、
  1. GO (Global Object) オブジェクトとして理解することもできます。このオブジェクトは表示できません (印刷できません) ため、すべて # と宣言されています。 ##var
  2. および
  3. let を使用して宣言されていないグローバル変数 変数 が GO オブジェクトに配置され、割り当てられる値は です未定義 (「変数プロモーション」を彷彿とさせます)分析 **関数宣言:** 次に、すべての関数宣言を GO オブジェクトに入れ、関数自体の関数本体に値を代入します (関数名が属性名、値が関数本体 関数名と変数名が同じ場合は容赦なく上書きされます)
  4. 事例説明
    <script>
        var a = 1;
        console.log(a);
        console.log(b);
        var b = 10;
        function fun (a) {
            console.log(b);
            var a = b = 2;
            var c = 123;
            console.log(a);
            console.log(b);
        }
        var a2 = 20
        fun(1);
     
    </script>
  5. 上記の手順と組み合わせると、

まず、

<script></script>
    で GO オブジェクト (ウィンドウ オブジェクト) が作成されます。コードを実行する前に
  1. GO = {
    	//自带的属性都不写
    }

    will 宣言されたすべてのグローバル変数と、

    var
  2. let

    を使用して宣言されていない変数は、GO オブジェクトに配置され、割り当てられます。値が 未定義<pre class="brush:php;toolbar:false">GO = { a : undefined, b : undefined, a2 : undefined }</pre>Anaization

    関数宣言
  3. の場合、関数名は属性名であり、値は関数本体です。関数名と変数名が同じだと容赦なく上書きされます
  4. GO = {
    	a : undefined,
    	b : undefined,
    	a2 : undefined,
    	function fun (a) {
        var a = b = 2;
        var c = 123;
      }
    }

    この時、JSコード実行前のプリコンパイル処理が完了し、JSコードまず、

    a に値 1
  5. が割り当てられ、対応する変更が GO オブジェクトにも行われます:
  6. GO = {
    	a : 1,
    	b : undefined,
    	a2 : undefined,
    	function fun (a) {
        var a = b = 2;
        var c = 123;
      }
    }

    次に a を出力します。このとき、GO オブジェクト上に変数 a が見つかり、このときの a の値は 1 であるため、

    console.log(a)
  7. は 1 になります。次に b を出力し、さらに GO オブジェクトを検索すると、b の値が
  8. 未定義

    であることがわかり、console.log(b) は 未定義と等しくなります。 次に代入ステートメントを実行します:

    b = 10;
  9. このとき、GO オブジェクトの
  10. b の値は 10

    ## になります。 #

    GO = {
    	a : 1,
    	b : 10,
    	a2 : undefined,
    	function fun (a) {
    		var a = b = 2;
    		var c = 123;
    	}
    }
    コードの次の行は **fun 関数ですが、この時点では実行されません。
  11. これは、前のプリコンパイル プロセスで、実際にはコードのフロントエンド、つまり伝説の宣言が事前に
  12. になっていたため、無視されました。次に、代入操作

    a2 に実行します: a2 = 20、GO オブジェクトも変更されます:

    GO = {
    	a : 1,
    	b : 10,
    	a2 : 20,
    	function fun (a) {
    		var a = b = 2;
    		var c = 123;
    	}
    }
    次に、fun を実行します。 関数は、前述の別の時点で行われるプリコンパイルなど、関数が実行される前に行われますが、ここで関数が実行される前のプリコンパイルについて説明します。
  13. 2. 関数実行前のプリコンパイル

関数呼び出しでは、独自のスコープ (**AO: **Activetion Object、実行コンテキスト)

AO

アクティブ オブジェクト。
    関数が呼び出されるとき、関数は実行の直前に生成されます。複数の関数呼び出しがある場合、複数の AO が生成されます
  1. AO オブジェクトの生成 : 関数が実行される直前に、AO アクティブ オブジェクト

    1. が AO 属性を分析して生成します: 仮パラメータ
    2. 変数宣言## を見つけます# そして、それらを AO オブジェクトに入れます。割り当てられた値は 未定義関数宣言を分析します: 関数宣言を見つけて、それを AO オブジェクトに入れて割り当てます。関数本体に。関数名は属性名、値は関数本体です。
    3. AO オブジェクト上で同じ名前の属性が見つかった場合、容赦なく上書きされます

    1 行ずつ実行します。

  2. ケースの説明
  3. 私が取り上げたコード例は上記のものです。

最初のステップは、AO オブジェクトを作成することです

AO{

}
    Find
  1. 仮パラメータ

    and

    変数宣言
  2. それを AO オブジェクトに入れて
  3. unknown

    ; 注: fun 関数の b は var によって宣言されていませんなので、これはグローバル変数なので、fun

    の AO には配置されません。

    AO{
    	a: undefined,//形参a与局部变量a同名
    	c: undefined
    }
    実際のパラメータを
    形式パラメータに割り当てます
  4. AO{
    	a: 1,
    	c: undefined,
    }

    検索関数宣言は AO オブジェクトに配置され、関数本体として割り当てられます。fun 関数には関数宣言がないため、この手順は無視されます。

  5. 函数执行之前的预编译完成,开始执行语句

  6. 执行代码

    1. 首先执行打印变量b,而此时fun的AO里边并没有变量b,所以会去GO对象里边找,此时的GO对象b的值为10,所以第一行代码打印出10;

    2. 第二行代码首先要看的是b = 2,然后GO对象里边b的值就被改为2了。

      GO = {
      	a : 1,
      	b : 10,
      	a2 : 20,
      	function fun (a) {
      		var a = b = 2;
      		var c = 123;
      	}
      }
    3. 然后b再赋值给a,变量a是属于局部变量a,所以fun的AO对象里边a的值被改为2。

      AO{
      	a: 2,
      	c: undefined,
      }
    4. 接着下一个赋值语句是c = 123,所以AO对象中c的值被改为了123

      AO{
      	a: 2,
      	c: 123,
      }
    5. 此时再执行console.log(a)的值就是AO对象里边a的值 2;执行console.log(b)的值就是GO对象b的值 2,至此函数fun执行完毕,紧跟着fun的AO也会被销毁

  7. 综上所述,依次打印出来的值为:1,undefined,10,2,2

总结

预编译两个小规则:

  1. 函数声明整体提升(无论函数调用和声明的位置是前是后,系统总会把函数声明移到调用前面)
  2. 变量声明提升(无论变量调用和声明的位置是前是后,系统总会把声明移到调用前,注意仅仅只是声明,所以值是undefined

预编译前奏

  1. imply global(暗示全局变量-专业术语) 即:任何变量,如果未经声明就赋值,则此变量就位全局变量所有。(全局域就是window,这里再一次说明了JavaScript是基于对象的语言,base on window)
  2. 一切声明的全局变量,全是window的属性;var a=12;等同于window.a = 12;(会造成window这个对象特别臃肿)
  3. 函数预编译发生在函数执行前一刻(懒加载机制)

相关推荐:javascript学习教程web前端开发视频教程

以上がJavaScriptのプリコンパイルプロセスを完全にマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。