目錄
階段(三)
預先編譯過程
1. JavaScript程式碼執行之前的預編譯
案例說明
2. 函數執行前的預編譯
总结
预编译两个小规则:
预编译前奏
首頁 web前端 js教程 完全掌握JavaScript預編譯過程

完全掌握JavaScript預編譯過程

Feb 10, 2022 pm 05:57 PM
html javascript 前端

本篇文章為大家帶來了關於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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1426
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1253
24
HTML 中的表格邊框 HTML 中的表格邊框 Sep 04, 2024 pm 04:49 PM

HTML 表格邊框指南。在這裡,我們以 HTML 中的表格邊框為例,討論定義表格邊框的多種方法。

HTML 中的巢狀表 HTML 中的巢狀表 Sep 04, 2024 pm 04:49 PM

這是 HTML 中巢狀表的指南。這裡我們討論如何在表中建立表格以及對應的範例。

HTML 左邊距 HTML 左邊距 Sep 04, 2024 pm 04:48 PM

HTML 左邊距指南。在這裡,我們討論 HTML margin-left 的簡要概述及其範例及其程式碼實作。

HTML 表格佈局 HTML 表格佈局 Sep 04, 2024 pm 04:54 PM

HTML 表格佈局指南。在這裡,我們詳細討論 HTML 表格佈局的值以及範例和輸出。

HTML 輸入佔位符 HTML 輸入佔位符 Sep 04, 2024 pm 04:54 PM

HTML 輸入佔位符指南。在這裡,我們討論 HTML 輸入佔位符的範例以及程式碼和輸出。

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在這裡我們也分別討論了 HTML 有序列表和類型的介紹以及它們的範例

HTML onclick 按鈕 HTML onclick 按鈕 Sep 04, 2024 pm 04:49 PM

HTML onclick 按鈕指南。這裡我們分別討論它們的介紹、工作原理、範例以及各個事件中的onclick事件。

See all articles