JavaScript - Hoisting(提升) 介紹

就在剛剛,看完了Will保哥的技術交流直播,在直撥最後結尾的時候

保哥對於Junior的前端工程師表示,他面試過的Devoloper幾近九成沒聽過 Hoisting 是什麼東西。

因為對於直接接觸網頁、JavaScript的開發者來說,難免會lost掉一些基本觀念。

於是這篇文章就誕生了。

根據 W3School  的網頁介紹中,我們發現第一句話就這樣寫著:

Hoisting is JavaScript's default behavior of moving declarations to the top.

翻譯成中文的意思就是 ,在JavaScript程式語言當中,它會自動幫你把你有宣告的變數、Function自動拉至最上方。

而這樣的行為,我們就稱為 Hoisting (提升)

以往我們在撰寫程式的時候,我們的觀念告訴我們:

程式碼就是由上而下執行,所有的變數、方法都需要經過宣告才能使用。

於是,當我們在撰寫像是Java、C#、Python等程式語言的時候,光是第一關 Compile 就不會過了。

原因是因為變數在還沒宣告的時候,並不會分配記憶體空間,自然就沒辦法操作其變數了。

但是JavaScript本身語言的特性,有著 Hoisting 的效果,所以即便你在使用變數後才進行變數宣告依然不會有Error發生。

所以相信大家在撰寫的時候都會有著這樣的寫法:

Hello(); // Hello World

function Hello() {

 console.log('Hello World');
}

在變數上我們可以這樣寫:

b = 200;
console.log(b); // 200
var b;

這時候會發現,因為Hoisting的效果,只要我們在使用後有進行宣告,那麼程式就不會有Error,也不會有undefined的情況發生。

但是有一種情況例外:

JavaScript Initializations are Not Hoisted

這句話的意思是:在JavaScript語言當中,如果將此初始化,則不會被 Hoisted (提升)

我們可以來試試看:

Hello();
var Hello = function() {
	console.log('Hello');
}

在我們寫完這一段Code,並執行時,我們會得到以下錯誤:

錯誤訊息告訴我們:Hello不是一個function。

而之所以會有這個錯誤訊息,正是呼應到剛剛上方的那一句話:

JavaScript Initializations are Not Hoisted

我們首先先在第一行呼叫Hello這個Function。

接著才將function指向給Hello這個變數。

其中第二行的寫法,它並不是一個宣告的行為,而是初始化的動作。

我宣告一個Hello的function,並將其指派給Hello這個變數。

這樣的動作,我們稱之為Initialize(初始化)

於是,第二行就不會有  Hoisting 的效果。

而同樣的,如果我們針對變數也這樣撰寫:

b++;
console.log(b); // NaN
var b = 200;

那麼會發現印出來的b,會是NaN。

那至於為什麼是NaN呢?

跟上述ㄧ樣的道理,因為初始化並不會被Hoisting(提升)

因此,第一行的b就不會有宣告的效果,所以若單獨把b印出來,結果會是 undefined。

而我們又把b給進行了++。

於是 undefined 再強制進行了+1的動作,這時候我們就會得到NaN的結果了。

看到這裡相信各位對於JavaScript的各種巫術感到非常頭痛。

因此在最後,W3School  在文末也表示:

對許多開發者來說,Hoisting(提升)是一種未知或被忽視的JavaScript行為。

如果開發人員不理解,那麼程式可能就會Error。

為了避免錯誤,請在每個任何變數或是方法使用前,都先進行宣告。

希望看完這篇的讀者能夠對於 JavaScript的 Hoisting 能夠有一定的認知。

但是最好還是都在使用前都進行宣告,否則未來維護你Code的人可是會痛不欲生的(笑

以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)

有任何家教、案子 或技術相關問題 請都歡迎聯繫我

http://www.zhenghui.idv.tw/