Javascript中的hoisting

前言

今天參加了六角學院 JavaScript 線上問答時,發現自己對於這個觀念上有些地方不太正確,所以寫一下做紀錄。

Hoisting

JavaScript 有一個很特別的東西叫做 hoisting,又稱提升、向上等

MDN 有解釋一下 Hositing 觀念。

提升看起來是單純地將變數和函式宣告,移動到程式的區塊頂端,然而並非如此。變數和函數的宣告會在編譯階段就被放入記憶體,但實際位置和程式碼中完全一樣。

所以由此可知 Hositing 主要跟記憶體有關係,因為JavaScript在執行前會先將變數 (var) 和函數 (function) 提升至最前面儲存在記憶體中,後面再依照相對應做賦值或處理。

範例(var)

1
2
console.log(a);
var a = 1;

這是一個很常見的 Hoisting 範例,但是這時候會發現 a 出現 undefined

如果依照前面觀念來講試著將問題給拆解來看。

1
2
3
var a
console.log(a);
a = 1;

圖解來講的話就是這樣。

var a 會被提升到 console.log(a) 前面,但是此時的 console.log(a) 還沒有任何東西,所以才會出現 undefined

範例(function)

1
2
3
4
5
a();

function a() {
console.log('王小明');
}

這個也是一個滿常見的 Hoisting 範例,依照一般程式碼的執行方式就是由上至下跑,但是因為 Hoisting 特性 function 會被提升到比 a(); 還前面,但是 function 中的變數 (var) 只會在你執行 function 的時候才會建立這個變數,但是 function 執行完畢後,就會消滅剛剛建立的變數,所以 function 中作業會比較省記憶體。

1
2
3
4
5
function a() {
console.log('王小明');
}

a();

圖解來講就是這樣。

結論

所以基本上 Hositing 就是將變數&函數提升到所有程式碼最前面,然後先存進記憶體中,後面在做賦值等動作。

由此可知 Hositing 主要跟記憶體有關係,而 Hositing 只是一個觀念。

補充觀念

JavaScript 執行環境有兩個重點。

  • 執行時會載入以下兩個東西
    • window 物件
    • this
  • 分兩階段執行
    • 創造階段 (creation),並會有外部環境
    • 執行階段

所謂創造階段就是先將變數&函數創造,然後再執行賦值或其他動作等。

參考

MDN: https://developer.mozilla.org/zh-TW/docs/Glossary/Hoisting
六角學院共筆: https://quip.com/oCBZAmsfvECS/419-JS-

0%