ES6 章節:Let 的 Hoisting (暫時性死區 TDZ)

Vicky
宅宅薇琪 [前端學習筆記]
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 的值,而是出現「暫時性死區」。此「暫時性死區」無法去存取變數。

總結

  1. let 一樣有「創造階段」會將程式碼提升。
  2. 從「創造階段」到「實際宣告的階段」中間會出現「暫時性死區」(TDZ),這個區域無法呼叫變數。
  3. 有「創造」到「執行」的概念,但不會預先出現 undefined,而是直接跳出錯誤提示。
  4. 文件裡都不會表明這和 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

--

--