ES6 章節:Let 的 Hoisting (暫時性死區 TDZ)
Published in
4 min readFeb 24, 2021
前面章節有提到,使用 var 宣告變數時,會有 Hoisting 狀態。那 let 到底有沒有 Hoisting 呢 ? 什麼是 Hoisting ? 先來複習一下~
Hoisting 會分為「創造」、「執行階段」
✏️ 以 var 宣告變數為例
console.log(Ming); //undefined
var Ming = '小明';
拆解
// 創造
var Ming;
// 執行
console.log(Ming); // undefined (若在賦予值之前試圖取得變數值的話,得到 undefined )
Ming = '小明'; // 在後面才賦予值
✏️ 以 let 宣告變數為例
console.log(Ming);// 跳錯 ReferenceError,(無法在初始化之前試圖取得此變數)
let Ming = '小明';
{
console.log(Ming);
// 跳錯 ReferenceError,(無法在初始化之前試圖取得此變數)
let Ming = '杰倫';
}
拆解來看看 let 到底有沒有 Hoisting
console.log(Ming);// 跳錯 ReferenceError,(無法在初始化之前試圖取得此變數)
let Ming = '小明';
{
// 創造
let Ming; // 執行
console.log(Ming);
// 跳錯 ReferenceError,(無法在初始化之前試圖取得此變數)
let Ming = '杰倫';
}
在創造階段的 let Ming; 到 執行階段的 let Ming = '杰倫';
這段會產生一個「暫時性死區」(簡稱 TDZ),在「暫時性死區」內無法取得變數值。- let 也有提升的概念,只是在提升時不會給變數賦予 undefined 的值,而是出現「暫時性死區」。此「暫時性死區」無法去存取變數。
總結
- let 一樣有「創造階段」會將程式碼提升。
- 從「創造階段」到「實際宣告的階段」中間會出現「暫時性死區」(TDZ),這個區域無法呼叫變數。
- 有「創造」到「執行」的概念,但不會預先出現 undefined,而是直接跳出錯誤提示。
- 文件裡都不會表明這和 var 的 Hoisting 是相同的概念。(只會說明 let 有「暫時性死區」(TDZ))。
呼應 “總結” 裡的第 2 點,再來一個範例試試看
從「創造階段」到「實際宣告的階段」中間會出現「暫時性死區」(TDZ),這個區域無法呼叫變數。
並無宣告變數 a,若試著取變數 a 的型別會出現 undefined,但不會跳錯。
console.log(a); // a is not defined (並無宣告變數 a)
console.log(typeof a); // undefined (不會跳錯)
試圖在宣告 let 之前取得 let 所宣告的變數 myName,會跳錯。
console.log(typeof myName);
// 跳錯 ReferenceError (無法在初始化之前試圖取得 let 所宣告的變數)
let myName = '';
✏️ 範例 : 觀察把 console.log 移至 “前方” 或 “後方” 的執行結果
注意使用 let 和 const 的錯誤碼有何不同~
使用 let 跳錯 : ReferenceError (找不到變數:拼錯字)
- 當試圖存取一個不存在的變數時,會拋出 ReferenceError,這個錯誤經常發生在拼錯字的情況。
使用 const 跳錯 : SyntaxError (語法錯誤)
- 當有程式碼違反 JavaScript 的語法規則時,會拋出 SyntaxError 的錯誤。
let a;
console.log(a); // undefined
使用 let 跳錯 : ReferenceError
console.log(a);
// 跳錯,ReferenceError: Cannot access 'a' before initialization
let a;
使用 let 跳錯 : ReferenceError
a(); // 跳錯,ReferenceError: Cannot access 'a' before initialization
let a = function(){
console.log('a');
}
const 宣告時候需要賦予值,否則會出現語法錯誤 (SyntaxError)
const a;
console.log(a);
// 跳錯,SyntaxError: Missing initializer in const declaratio