參考文檔: let 和 const 命令 - ECMAScript6入門
理解ES6中的TDZ(暫時性死區)
注:文中代碼僅作示意,復制運行時需要適當調整
ES6 規定,如果代碼區塊中存在 let 和 const 命令聲明的變量,這個區塊對這些變量從一開始就形成了封閉作用域,直到聲明語句完成,這些變量才能被訪問(獲取或設置),否則會報錯ReferenceError。這在語法上稱為“暫時性死區”(英temporal dead zone,簡 TDZ),即代碼塊開始到變量聲明語句完成之間的區域。
通過 var 聲明的變量擁有變量提升、沒有暫時性死區,作用於函數作用域:
-
- 當進入變量的作用域(包圍它的函數),立即為它創建(綁定)存儲空間,立即被初始化並被賦值為 undefined
- 當執行到變量的聲明語句時,如果變量定義了值則會被賦值
(function fn() { //函數作用域開始 console.log(temp) //undefined //聲明 var temp console.log(temp) //undefined //賦值 temp = 123 console.log(temp) //123 })() //在函數作用域外訪問 console.log(temp) //ReferenceError: temp is not defined
通過 let 聲明的變量沒有變量提升、擁有暫時性死區,作用於塊級作用域:
-
- 當進入變量的作用域(包圍它的語法塊),立即為它創建(綁定)存儲空間,不會立即初始化,也不會被賦值
- 訪問(獲取或設置)該變量會拋出異常 ReferenceError
- 當執行到變量的聲明語句時,如果變量定義了值則會被賦值,如果變量沒有定義值,則被賦值為undefined
{ //函數作用域開始,TDZ開始 console.log(temp) //ReferenceError: temp is not defined //聲明 let temp console.log(temp) //ReferenceError: Cannot access 'temp' before initialization //賦值 temp = 345 //TDZ結束 console.log(temp) //345 //塊級作用域結束 } //在塊級作用域外訪問 console.log(temp) //ReferenceError: temp is not defined
通過 const 聲明的常量,需要在定義的時候就賦值,並且之后不能改變,暫時性死區與 let 類似。
{ //作用域開始,TDZ開始 console.log(temp) //ReferenceError: temp is not defined //聲明並賦值 const temp = 789 //TDZ結束 console.log(temp) //789 //給常量賦值 temp = 987 //TypeError: Assignment to constant variable //作用域結束 } //在作用域外訪問 console.log(temp) //ReferenceError: temp is not defined
一句話總結:在塊級作用域中, let 和 const 聲明的變量、常量在聲明語句執行完成之前不能訪問(包括聲明語句本身)。
另外,容易因為 暫時性死區 而出錯的細節代碼在此不展開舉例,參考文檔中有詳情舉例。
附:第一次寫學習筆記,寫隨筆花費的時間比學習相關內容的時間還要長,感覺有點本末倒置,不過以后回頭看應該會覺得有所值得吧!