1. 程式人生 > 其它 >JavaScript的預編譯問題

JavaScript的預編譯問題

技術標籤:js基礎javascriptjs

在js引擎解釋執行程式碼之前會有一個預編譯的過程

瞭解預編譯的過程,對於我們理解js程式碼的執行有很重要的意義,例如,為何函式的執行可以放在函式宣告之前,而變數的使用放在變數定義之前則會報出undefined,而使用沒有定義的變數又會直接報錯。
下面來看一下其原理吧。
(一)預編譯的過程
對於全域性程式碼,預編譯分為三步:

一、檢查var定義的變數,並存儲於全域性物件GO中,但此時並不賦值,GO(global object)是全域性執行上下文,也就是window物件。
二、檢查函式定義,並存儲於GO,此時其只儲存函式名於其函式表示式所在的地址,並不看錶達式的具體內容。
三、執行函式體。

而在執行函式時,也會進行預編譯,其預編譯過程有四步:

一、檢查var定義的變數,並存儲於AO中,此時並不賦值。AO(Activation Object)是函式執行上下文,在函式開始執行是建立(即預編譯之前)。
二、檢查函式體內的引數,並將其替換為傳入的引數arguments[i]。
三、檢查函式定義,並存儲於AO。
四、執行函式體。

注意:
一、對於變數,預編譯過程中只是宣告,而並不賦值,如下例所示:

<script>
	console.log(a)
	var a = 5
</script>

由於在預編譯中,沒有對a賦值,在函式體執行之前,GO = {a: undefinrd, …},所以控制檯輸出undefined

賦值會在函式體執行的過程中給進行。
二、對於函式,預編譯時會把函式表示式的記憶體地址同函式名存進所以,函式的宣告和執行語句可以逆序。

(二)擴充套件
函式預編譯過程中用到的GO、AO涉及到了函式作用域和作用域鏈的問題,也跟預編譯的過程相關,將在下個博文討論。