首先要先了解 JS 執行方式分為 2 階段運作 :
- 建立期:註冊名稱 + 初始化
- 執行期:執行函數/賦值
用下面程式來看
在 建立期 的時候第 1 行執行的部分會先跳過,第 2 行會宣告 a 變數並初始化 a = undefined
console.log(a) // 不做事
var a = 1 // 宣告 a, 初始化 a = undefined
在 執行期 的時候第 1 行執行印出 a (當下的 a 是 undefined) ,第 2 行的時候才會對 a 進行賦值
console.log(a) // 執行 印出 undefined
var a = 1 // 賦值 a = 1
用 var 宣告的變數會先初始化,因此即使在宣告前就使用該變數也不會出現錯誤,只會出現 undefined ↓
console.log(a) // 印出 undefined
var a = 1
if (false) {
var a = 1 // 建立期會宣告 a
}
console.log(a) // 印出 undefined
若是用 let / const 宣告的變數在建立期 不會初始化
因此下列程式碼會出錯 ↓
console.log(a) // error
let a = 1
用下面程式來看
在 建立期 的時候第 1 行執行的部分會先跳過,第 2 行會宣告 a 變數
console.log(a) // 不做事
let a = 1 // 宣告 a
在 執行期 的時候第 1 行執行要印出 a 但 a 尚未初始化所以會出錯
console.log(a) // error: a 未初始化
let a = 1
※ 變數提昇是因 JS 分兩階段執行導致的結果,var、let、const 都有變數提昇
但 let & const 不會幫變數做初始化,因此會出錯
※ 當用 let / const 宣告時,變數在被賦值之前會不能使用
這段時間就是所謂的 TDZ 暫時死區 (Temporal Dead Zone)