在前幾天中我已經提過 提升(Hoisting)
這個專有名詞,它是 JavaScript 中的一個重要概念。單從字面上比較難理解它的意思,甚至引起誤解。今天就來看看這到底是甚麼吧。
提升(Hoisting)
是 JavaScript 中的一個行為,簡單來說就是在程式碼執行之前,
會將變數(var)和函式宣告提升到它們所在作用域的頂部,
這使得你在作用域中可以在宣告之前訪問這些變數或函數。
但以上只是對提升的一種比較直覺性的說明,我們可以看看 MDN 對提升
的描述:
提升看起來是單純地將變數和函式宣告,移動到程式的區塊頂端,然而並非如此。
變數和函數的宣告會在編譯階段就被放入記憶體,但實際位置和程式碼中完全一樣。
單從定義可能還是難以理解,我們來實際看看例子吧。
var
的宣告會被提升,但 let
和 const
不會。
來看看以下程式碼:
console.log(x); // 輸出: undefined
var x = 5;
console.log(x); // 輸出: 5
因為提升的效果,實際執行起來會是像這樣(實際程式碼位置不變):
var x;
console.log(x); // 輸出: undefined
x = 5;
console.log(x); // 輸出: 5
另外 let
和 const
不會被提升,範例如下:
console.log(y); // 報錯,在宣告之前無法訪問 y
let y = 5;
console.log(y);
sayHello(); // 輸出: "Hello, World!"
function sayHello() {
console.log("Hello, World!");
}
num = 6;
num + 7;
var num;
/* 只要 num 有被宣告,就不會有錯誤 */
console.log(sayBye); // 輸出: undefined
sayBye(); // 報錯
var sayBye = function() {
console.log("Bye!");
}
我們先來看函式的部分。在執行程式碼之前,JavaScript 會將函式宣告放進記憶體裡面,這樣做的優點是:可以在程式碼宣告該函式之前使用它。這大大增加了開發的靈活性。
但對於變數(var)而言,提升的特性反而容易造成不符合預期的結果。
例如使用 var 宣告一個變數並賦予初始值,但在宣告之前訪問它們時,仍會拿到 undefined 的值。
過度使用提升還可能會降低程式碼的可讀性和維護性。如果變數和函數的宣告散佈在程式碼的各個地方,可能會讓程式碼難以理解和維護。
ES6 推出 let 和 const 並沒有保留提升的特性,就是想要解決其所帶來的的缺點。
這也是為何 var 不再被推薦使用的原因之一。
今天簡單介紹了提升(Hoisting)
,並在此總結一下特性:
參考資料: