首頁 > web前端 > js教程 > 主體

完全掌握JavaScript預編譯過程

WBOY
發布: 2022-02-10 18:05:35
轉載
1828 人瀏覽過

本篇文章為大家帶來了關於javascript中預編譯的相關知識,其中主要透過範例來介紹預編譯的相關問題,希望對大家有幫助。

完全掌握JavaScript預編譯過程

階段(三)

  1. 詞法語法分析:詞法語法分析就是檢查JavaScript程式碼是否有一些低階的語法錯誤
  2. 預編譯:本文主講
  3. 執行程式碼:執行程式碼就是js引擎解析程式碼,解析一行執行一行

這一章主要講預編譯流程

預先編譯過程

預先編譯也分成2個時間點:

  1. 第一個是在JavaScript程式碼執行之前
  2. 第二個是在函數執行之前。

但是JavaScript程式碼之前,之前的預編譯只發生一次,函數執行之前的預編譯是多次的。

1. JavaScript程式碼執行之前的預編譯

  1. JavaScript程式碼執行之前,首先會建立一個全域對象,可以理解為window對象,也可以理解為GOGlobal Object)對象,我們是看不到的(無法列印)
  2. 然後將所有聲明的全域變量未使用varlet聲明的變數放到GO物件中,並且賦值為undefined(聯想到“變數提升”)
  3. 分析**函數宣告:**然後再將所有的函數宣告也放到GO物件中,並且賦值為函數本身的函數體(函數名為屬性名稱,值為函數體,如果函數名稱和變數名稱相同,則無情覆寫)

案例說明

<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>
登入後複製

結合上面說的步驟:

  1. 首先,<script></script>中的程式碼執行之前會建立一個GO物件(window物件)

    GO = {
    	//自带的属性都不写
    }
    登入後複製
  2. #將所有宣告的全域變數、未使用varlet聲明的變數放到GO物件中,且賦值為undefined

    GO = {
    	a : undefined,
    	b : undefined,
    	a2 : undefined
    }
    登入後複製
  3. #分析函數宣告,函數名為屬性名稱,值為函數體,如果函數名稱和變數名稱相同,則無情覆寫

    GO = {
    	a : undefined,
    	b : undefined,
    	a2 : undefined,
    	function fun (a) {
        var a = b = 2;
        var c = 123;
      }
    }
    登入後複製
  4. 此時完成了js程式碼執行之前的預編譯過程,開始執行js程式碼,首先是給a進行賦值為1,在GO物件裡邊也會進行對應的改變:

    GO = {
    	a : 1,
    	b : undefined,
    	a2 : undefined,
    	function fun (a) {
        var a = b = 2;
        var c = 123;
      }
    }
    登入後複製
  5. 然後印出a,此時會在GO物件上去找變數a,然後此時的a的值為1,所以console.log(a) 是等於1的。接著印b,也會去GO物件上找,找到了b的值為undefined,所以console.log(b)是等於undefined

  6. 接著執行到賦值語句:b = 10; 此時GO物件裡b的值變成了10

    GO = {
    	a : 1,
    	b : 10,
    	a2 : undefined,
    	function fun (a) {
    		var a = b = 2;
    		var c = 123;
    	}
    }
    登入後複製
  7. 接著下一行程式碼是一個**fun函數,此時不會去執行該函數**,因為在前面的預編譯過程中實際上是被放到了代碼的最前端,就是傳說中的聲明提前,所以忽略掉了。接著給a2進行賦值操作a2 = 20,GO物件也會改變:

    GO = {
    	a : 1,
    	b : 10,
    	a2 : 20,
    	function fun (a) {
    		var a = b = 2;
    		var c = 123;
    	}
    }
    登入後複製
    登入後複製
  8. 接著是執行fun函數,如同上面說到的另外一個時間點發生的預編譯,就是執行函數之前,現在就來說一下函數執行前的預編譯是怎麼樣的。

2. 函數執行前的預編譯

  1. #函數呼叫,也是會產生自己的作用域(**AO:**Activetion Object,執行期間上下文)AO活動物件。 函數呼叫時候,執行前的一瞬間產生的,如果有多個函數的呼叫,會產生多個AO

    1. #產生AO物件:函數執行前的一瞬間,產生AO活動物件
    2. 分析產生AO屬性:找出形參變數宣告放到AO對象,賦值為undefined
    3. 分析函數宣告:找出函數宣告放到AO物件並賦值為函數體。函數名為屬性名稱,值為函數體;

    如果遇到AO物件上屬性同名,則無情覆寫

  2. 逐行執行。

案例說明

拿的是上文中的程式碼範例。

  1. 第一步建立AO物件

    AO{
    
    }
    登入後複製
  2. #找出形參變數宣告放到AO物件並賦值為undefined

    注意:fun函數裡邊的b是未經var宣告的,所以是全域變量,不會被放在fun的AO上。

    AO{
    	a: undefined,//形参a与局部变量a同名
    	c: undefined
    }
    登入後複製
  3. 實參賦值到形參

    AO{
    	a: 1,
    	c: undefined,
    }
    登入後複製
  4. ##查找函數宣告放到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中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!