iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
自我挑戰組

複習 JavaScript 核心概念系列 第 5

[Day 05] 提升(Hoisting)

  • 分享至 

  • xImage
  •  

在前幾天中我已經提過 提升(Hoisting) 這個專有名詞,它是 JavaScript 中的一個重要概念。單從字面上比較難理解它的意思,甚至引起誤解。今天就來看看這到底是甚麼吧。

什麼是提升?

提升(Hoisting) 是 JavaScript 中的一個行為,簡單來說就是在程式碼執行之前,
會將變數(var)和函式宣告提升到它們所在作用域的頂部
這使得你在作用域中可以在宣告之前訪問這些變數或函數。

但以上只是對提升的一種比較直覺性的說明,我們可以看看 MDN提升的描述:

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

單從定義可能還是難以理解,我們來實際看看例子吧。


變數提升

  • 首先我們要知道 var 的宣告會被提升,但 letconst 不會。
  • 提升的只有宣告本身,賦值的部分並不會被提升。

來看看以下程式碼:

console.log(x); // 輸出: undefined
var x = 5;
console.log(x); // 輸出: 5

因為提升的效果,實際執行起來會是像這樣(實際程式碼位置不變):

var x;
console.log(x); // 輸出: undefined
x = 5;
console.log(x); // 輸出: 5

另外 letconst 不會被提升,範例如下:

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),並在此總結一下特性:

  • 函式可以被提升,使其可以在宣告之前呼叫使用
  • 變數(var)可以被提升,使其可以在宣告之前被訪問,但賦予初始值的部分不會被提升
  • let 和 const 不會被提升,在宣告之前無法訪問

參考資料:


上一篇
[Day 04] 作用域(Scope)
下一篇
[Day 06] 記憶體管理
系列文
複習 JavaScript 核心概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言