Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

搞懂JS-什麼是hoisting?

Imgur

JS 在編譯時,會將宣告的變數、函式都先存放到一個記憶體空間,很像是被提升到最前面,賦值不會跟著被提升,實際運行時,再把值塞進剛剛存放的記憶體空間裡。

變數提升(Variable hoisting)

先來看個範例:
我 log 了一個從未宣告的變數 dog

1
console.log(dog);

會出現 Uncaught ReferenceError: dog is not defined 的錯誤,這非常合理!


那如果先 log 出下面的變數會發生什麼事?

1
2
console.log(dog);
var dog = "bobee";

出現了 undefined!!為什麼不是 ReferenceError: dog is not defined 呢?

這是因為宣告的變數先被存放到記憶體空間了,而賦值不會被提升,你可以想成這樣
1
2
3
var dog;
console.log(dog);
dog = "bobee";

注意!var dog 並不是真的被放到最前面,而是記憶體空間先存放了 dog,才會繼續依照執行順序運行程式碼,因此 log 會是 undefined,在執行程式碼之前,記憶體空間會是這樣

1
2
3
globle scope: {
dog: undefined
}

在函式裡宣告的變數也會被放到 function scope 的記憶體空間
1
2
3
4
function dog() {
console.log(bark);
var bark = "woof";
}

執行起來時會像是這樣:

1
2
3
4
5
function dog() {
var bark;
console.log(bark);
bark = "woof";
}

函式提升(Function hoisting)

函式有分為函式陳述式(具名函式)、函式表達式(匿名函式)兩種,其中函式陳述式會被提升,函式表達式不會被提升,我們來看看範例。

函式陳述式

1
2
3
4
5
dog();
function dog() {
var bark = "woof";
console.log(bark);
}

結果會是 woof
dog()放在函式之前,卻可以 log 出我們要的結果,這是 hoisting 的關係,可以想成這樣

1
2
3
4
5
function dog() {
var bark = "woof";
console.log(bark);
}
dog();

函式表達式

1
2
3
4
5
dog();
var dog = function () {
var bark = "woof";
console.log(bark);
};

結果變成 Uncaught TypeError: dog is not a function

這是因為宣告的變數先被提升了,會變成這個樣子

1
2
3
4
5
6
var dog;
dog();
dog = function () {
var bark = "woof";
console.log(bark);
};

我們在呼叫 dog 時還不是個 function,因此會噴出 TypeError 的錯誤

函式的 hoisting 可以輕易達成遞迴函式

1
2
3
4
5
6
7
8
9
10
11
function even(n) {
if (n === 0) return true;
return odd(n - 1);
}

function odd(n) {
if (n === 0) return false;
return even(n - 1);
}

even(10);

我們在 even 裡面呼叫 odd,在 odd 裡面也呼叫 even,這種遞迴狀況如果沒有 hoisting 是沒辦法解決的。

函式與變數同名,函式優先

1
2
3
console.log(dog); // fn dog(){}
var dog;
function dog() {}

函式的優先權比變數高,如有多個函式,將會覆蓋前面的


let 與 const 也有 hoisting

在上一篇var, let, const 概念就有講到, let、const 也是會有 hoisting 的,差別在於提升之後,var 宣告的變數會被初始化為 undefined,而 let 與 const 的宣告不會被初始化為 undefined,而且如果你在「賦值之前」就存取它,就會拋出錯誤。

在「提升之後」以及「賦值之前」這段期間被稱為「暫時死區」(Temporal Dead Zone,TDZ),可以幫助我們養成在變數還沒宣告之前,不要使用他的好習慣,讓程式碼可讀性提高。




hoisting 的筆記就告一段落,了解正確觀念真的很重要,歡迎路過多多指教,一起學習程式吧 😀


推薦閱讀: 我知道你懂 hoisting,可是你了解到多深?




Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️