本篇文章為大家帶來了關於javascript中預編譯的相關知識,其中主要透過範例來介紹預編譯的相關問題,希望對大家有幫助。
階段(三)
- 詞法語法分析:詞法語法分析就是檢查JavaScript程式碼是否有一些低階的語法錯誤
- 預編譯:本文主講
- 執行程式碼:執行程式碼就是js引擎解析程式碼,解析一行執行一行
這一章主要講預編譯流程
預先編譯過程
預先編譯也分成2個時間點:
- 第一個是在JavaScript程式碼執行之前
- 第二個是在函數執行之前。
但是JavaScript程式碼之前,之前的預編譯只發生一次,函數執行之前的預編譯是多次的。
1. JavaScript程式碼執行之前的預編譯
- JavaScript程式碼執行之前,首先會建立一個全域對象,可以理解為
window
對象,也可以理解為GO(Global Object
)對象,我們是看不到的(無法列印) - 然後將所有聲明的全域變量、未使用
var
和let
聲明的變數放到GO物件中,並且賦值為undefined
(聯想到“變數提升”) - 分析**函數宣告:**然後再將所有的函數宣告也放到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>
結合上面說的步驟:
-
首先,
<script></script>
中的程式碼執行之前會建立一個GO物件(window物件)GO = { //自带的属性都不写 }
-
#將所有宣告的全域變數、未使用
var
和let
聲明的變數放到GO物件中,且賦值為undefined
GO = { a : undefined, b : undefined, a2 : undefined }
-
#分析函數宣告,函數名為屬性名稱,值為函數體,如果函數名稱和變數名稱相同,則無情覆寫
GO = { a : undefined, b : undefined, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }
-
此時完成了js程式碼執行之前的預編譯過程,開始執行js程式碼,首先是給a進行賦值為1,在GO物件裡邊也會進行對應的改變:
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)
是等於1的。接著印b,也會去GO物件上找,找到了b的值為undefined
,所以console.log(b)是等於undefined
。-
接著執行到賦值語句:
b = 10;
此時GO物件裡b的值變成了10GO = { a : 1, b : 10, a2 : undefined, function fun (a) { var a = b = 2; var c = 123; } }
-
接著下一行程式碼是一個**
fun
函數,此時不會去執行該函數**,因為在前面的預編譯過程中實際上是被放到了代碼的最前端,就是傳說中的聲明提前,所以忽略掉了。接著給a2進行賦值操作:a2 = 20
,GO物件也會改變:GO = { a : 1, b : 10, a2 : 20, function fun (a) { var a = b = 2; var c = 123; } }
接著是執行
fun
函數,如同上面說到的另外一個時間點發生的預編譯,就是執行函數之前,現在就來說一下函數執行前的預編譯是怎麼樣的。
2. 函數執行前的預編譯
-
#函數呼叫,也是會產生自己的作用域(**AO:**Activetion Object,執行期間上下文)AO活動物件。 函數呼叫時候,執行前的一瞬間產生的,如果有多個函數的呼叫,會產生多個AO
- #產生AO物件:函數執行前的一瞬間,產生AO活動物件
-
分析產生AO屬性:找出形參與變數宣告放到AO對象,賦值為
undefined
- 分析函數宣告:找出函數宣告放到AO物件並賦值為函數體。函數名為屬性名稱,值為函數體;
如果遇到AO物件上屬性同名,則無情覆寫
逐行執行。
案例說明
拿的是上文中的程式碼範例。
-
第一步建立AO物件
AO{ }
-
#找出形參與變數宣告放到AO物件並賦值為
undefined
;注意:
fun
函數裡邊的b是未經var宣告的,所以是全域變量,不會被放在fun
的AO上。AO{ a: undefined,//形参a与局部变量a同名 c: undefined }
-
將實參賦值到形參上
AO{ a: 1, c: undefined, }
- ##查找函數宣告放到AO物件並賦值為函數體,fun函數沒有函數聲明,所以忽略這一步。
函数执行之前的预编译完成,开始执行语句
-
执行代码
首先执行打印变量b,而此时
fun
的AO里边并没有变量b,所以会去GO对象里边找,此时的GO对象b的值为10,所以第一行代码打印出10;-
第二行代码首先要看的是
b = 2
,然后GO对象里边b的值就被改为2了。GO = { a : 1, b : 10, a2 : 20, function fun (a) { var a = b = 2; var c = 123; } }
-
然后b再赋值给a,变量a是属于局部变量a,所以
fun
的AO对象里边a的值被改为2。AO{ a: 2, c: undefined, }
-
接着下一个赋值语句是
c = 123
,所以AO对象中c的值被改为了123AO{ a: 2, c: 123, }
此时再执行
console.log(a)
的值就是AO对象里边a的值 2;执行console.log(b)
的值就是GO对象b的值 2,至此函数fun执行完毕,紧跟着fun的AO也会被销毁。
综上所述,依次打印出来的值为:
1,undefined,10,2,2
。
总结
预编译两个小规则:
- 函数声明整体提升(无论函数调用和声明的位置是前是后,系统总会把函数声明移到调用前面)
- 变量声明提升(无论变量调用和声明的位置是前是后,系统总会把声明移到调用前,注意仅仅只是声明,所以值是
undefined
)
预编译前奏
-
imply global(暗示全局变量-专业术语)
即:任何变量,如果未经声明就赋值,则此变量就位全局变量所有。(全局域就是window
,这里再一次说明了JavaScript是基于对象的语言,base on window
) - 一切声明的全局变量,全是
window
的属性;var a=12;
等同于window.a = 12;
(会造成window
这个对象特别臃肿) - 函数预编译发生在函数执行前一刻(懒加载机制)
相关推荐:javascript学习教程、web前端开发视频教程
以上是完全掌握JavaScript預編譯過程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

WebStorm Mac版
好用的JavaScript開發工具

記事本++7.3.1
好用且免費的程式碼編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。