首頁  >  文章  >  web前端  >  JavaScript預編譯流程的詳細解析(程式碼範例)

JavaScript預編譯流程的詳細解析(程式碼範例)

不言
不言轉載
2019-01-24 09:15:192592瀏覽

這篇文章帶給大家的內容是關於JavaScript預編譯流程的詳細解析(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

大家都知道JavaScript是解釋型語言,既然是解釋型語言,就是編譯一行,執行一行,那又何來預編譯一說呢?腳本執行js引擎都做了什麼呢?今天我們就來看看吧。

1-JavaScript運行三部曲

  1. #語法分析

  2. 預編譯

  1. ##解釋執行

  2. 語法分析很簡單,就是引擎檢查你的程式碼有沒有什麼低階的語法錯誤;解釋執行顧名思義便是執行程式碼了;預編譯簡單理解就是在記憶體中開闢一些空間,存放一些變數與函數;

  3. 2-JS預編譯什麼時候發生
  4. #預編譯到底什麼時候發生?誤以為預編譯僅僅發生在script內程式碼區塊執行前這倒並沒有錯預編譯確確實實在script程式碼內執行前發生了但是它大部分會發生在函數執行前

  5. 3-實例分析
  6. 先來區分理解一下這2個概念:變數宣告var ... 函數宣告function(){}

    <script>
    var a = 1;
    console.log(a);
    function test(a) {
      console.log(a);
      var a = 123;
      console.log(a);
      function a() {}
      console.log(a);
      var b = function() {}
      console.log(b);
      function d() {}
    }
    var c = function (){
    console.log("I at C function");
    }
    console.log(c);
    test(2);
    </script>
  7. 分析流程如下:
頁面產生便建立了GO全域對象(Global Object)(也就是window物件);
    第一個腳本檔案載入;
  1. 腳本載入完畢後,分析語法是否合法;
  2. 開始預編譯查找變數聲明,作為GO屬性,值賦予undefined;尋找函數聲明,作為GO屬性,值賦予函數體;
  3. 預編譯
  4. //抽象描述
        GO/window = {
            a: undefined,
            c: undefined,
            test: function(a) {
                console.log(a);
                var a = 123;
                console.log(a);
                function a() {}
                console.log(a);
                var b = function() {}
                console.log(b);
                function d() {}
            }
        }

    解釋執行程式碼(直到執行呼叫函數test(2)語句)

    //抽象描述
        GO/window = {
            a: 1,
            c: function (){
                console.log("I at C function");
            }
            test: function(a) {
                console.log(a);
                var a = 123;
                console.log(a);
                function a() {}
                console.log(a);
                var b = function() {}
                console.log(b);
                function d() {}
            }
        }
  5. 執行函數test()之前,發生預編譯
建立AO活動物件(Active Object);
尋找形參和變數聲明,值賦予undefined;

實參值賦給形參;JavaScript預編譯流程的詳細解析(程式碼範例)

查找函數聲明,值賦予函數體;

前面1、2兩小步驟如下:
//抽象描述
    AO = {
        a:undefined,
        b:undefined,
    }
預編譯之第3步如下:
    //抽象描述
            AO = {
                a:2,
                b:undefined,
            }
  1. 預編譯之第4步如下:

    //抽象描述
        AO = {
            a:function a() {},
            b:undefined
            d:function d() {}
        }
    執行test()函數時如下程序變更:
  2. //抽象描述
        AO = {
            a:function a() {},
            b:undefined
            d:function d() {}
        }
        --->
        AO = {
            a:123,
            b:undefined
            d:function d() {}
        }
        --->
        AO = {
            a:123,
            b:function() {}
            d:function d() {}
        }
  3. 執行結果:

  4. #注意:
  5. #預編譯階段發生變數宣告和函數聲明,沒有初始化行為(賦值),匿名函數不參與預編譯; 只有在解釋執行階段才會進行變數初始化;

  6. #預編譯(函數執行前)
    創建AO物件(Active Object)
  1. 查找函數形參及函數內變數聲明,形參名及變數名稱作為AO物件的屬性,值為undefined
  2. 實參形參相統一,實參值賦給形參
    找出函數聲明,函數名稱作為AO物件的屬性,值為函數引用
  • 預先編譯(腳本程式碼區塊script執行前)
  1. 查找全域變數宣告(包含隱式全域變數聲明,省略var宣告),變數名作全域物件的屬性,值為undefined
  2. 查找函數聲明,函數名稱作為全域物件的屬性,值為函數引用
  • ##預先編譯小結

    1. 預先編譯兩個小規則
    2. #函數宣告整體提升-(具體點說,無論函數呼叫和宣告的位置是前是後,系統總是會把函數宣告移到呼叫前面)

    變數宣告提升-(具體點說,無論變數呼叫和宣告的位置是前後,系統總是會把宣告移到呼叫前,注意只是聲明,所以值是undefined)
  • #預編譯前奏

    ############################################### ###imply global 即任何變量,如果未經聲明就賦值,則此變量就位全域變量所有。 (全域是Window)############一切宣告的全域變量,全是window的屬性;var a = 12;等同於Window.a = 12;######## ########函數預編譯發生在函數執行前一刻。 ################

    以上是JavaScript預編譯流程的詳細解析(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除