var
支援 Hoisting, 因此可在執行之後才使用 var
宣告 variable 與 function;但 let
不支援 Hoisting,只能在執行前先宣告好,因為 var
在 JavaScript Engine 的 Creation Phase 已經將 Variable 與 Function 建立完成。
Version
ECMAScript 5
var
console.log(name)
foo()
var name = 'Sam'
function foo() {
console.log('foo')
}
name
與 foo()
都在執行後才宣告。
實際執行發現 name
為 undefined
,但 foo()
卻可正常執行,why ?
JavaScript engine 在執行時分兩個時期:
- Creation Phase
- Execution Phase
在 creation phase 時,JavaScript engine 會將所有 variable 與 function 都載入 memory,無論 variable 或 function 宣告在實際執行程式之前或之後。
因此 name
與 foo()
都會先載入 memory。
此時 name
為 undefined
,foo()
則為完整 function 定義。
因此 console.log(name)
印出 undefined
,foo()
可印出 foo
。
name
將在 console.log()
與 foo()
執行完後才會指定為 Sam
。
var name = 'Sam'
console.log(name)
foo()
function foo() {
console.log('foo')
}
若要正確印出 Sam
,則必須在 console.log()
之前執行 var name = 'Sam'
。
如此 creation phase 雖然 name
為 undefined
,但 execution phase 隨即將 name
指定為 Sam
,因此可正常印出 Sam
。
let
console.log(name)
foo()
let name = 'Sam'
let foo = function() {
console.log('foo')
}
若由 var
改用 ES6 的 let
,則直接 runtime error。
因為 let
並不支援 hoisting,不會在 creation phase 建立 variable 與 function,因此不可在執行後才使用 let
宣告 variable 與 function。
let name = 'Sam'
console.log(name)
let foo = function() {
console.log('foo')
}
foo()
name
與 foo()
必須在執行前先使用 let
宣告後方可正常執行。
Conclusion
- 只有
var
才支援 hoisting,let
沒有支援 var
的 hoisting 是因為 variable 與 function 在 creation phase 已經完成配置,其中 variable 為undefined
,function 則包含完整定義,variable 必須在 execution phase 才會定義初始值