JavaScript的預編譯問題
阿新 • • 發佈:2020-12-31
技術標籤: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涉及到了函式作用域和作用域鏈的問題,也跟預編譯的過程相關,將在下個博文討論。