- 在 ES6 尚未流行前,大部分 JS 開發者都是使用 var 關鍵字做變數宣告,很多開發者在宣告函式時也比較習慣使用 function declaration 又稱作 function statement 做函式的宣告。
var cat = 'Civet';
// function declaration || function statement
function sayHi() {
var cat = 'Doraemon';
console.log("hello I'm " + cat);
}
sayHi();
- 而以上程式碼相信大家腦袋中早已有答案,我們在 Devtool 中將會看到字串 hello I'm Doraemon ,但如果今天的情況變成是以下程式碼?那結果會是如何呢?
var cat = 'Civet';
// function declaration || function statement
function sayHi() {
console.log("hello I'm " + cat);
var cat = 'Doraemon';
}
sayHi();
- 答案將會是 hello I'm undefined ,驚不驚喜,意不意外? cat 的值竟然不是向外找的 Civet 也沒有錯誤訊息說明 ReferenceError: cat is not defined 取而代之的值卻是 undefined ! 別緊張,通常一般教授 JS 的書籍會很貼心的先分解步驟給學者看,當然這裡也不意外。可以先想像上述的程式碼和下述的程式碼是等價的。
var cat = 'Civet';
// function declaration || function statement
function sayHi() {
var cat;
console.log("hello I'm " + cat);
cat = 'Doraemon';
}
sayHi();
-
這樣看起來是不是相對合理多了呢!? 這也是為何用提升 ( Hoisting ) 這個詞來描述這種現象,從 sayHi 這個函式當中我們看見了 cat 這個變數被 “提” 早於函式一開始前就做宣告,但並沒有初始化,也就是賦予了這個變數記憶體位置卻沒有賦予它值。而 JS 在此種情況會給予該變數 undefined 的值。
-
但為什麼會發生提升 ( Hoisting ) 這種現象呢? 這就要說到 JS 在運行時,會有兩個階段
-
創建階段 ( creation phase )