先看下暫時性死區的例子
let a = 1
if (true) {
console.log(a)
let b = 2
}
//輸出1
let a = 1
if (true) {
console.log(a)
let a = 2
}
//Uncaught ReferenceError:Cannot access 'a'
//before initialization
為什麼會出現這種情況呢?這就是我們今天要了解的js中的暫時性死區( temporal dead zone,簡稱TDZ );
先看關於ES6標準中關於暫時性死區的解釋:
The variables are created when their containing Lexical Environment is
instantiated but may not be accessed inany way until the variable’s
LexicalBinding is evaluated.
翻譯過來的意思就是:
當程式的控制流程在新的作用域(module function 或 block作用域)進行例項化時,在此作用域中用let/const宣告的變數會先在作用域中被建立出來,
但因此時還未進行詞法繫結,所以是不能被訪問的,如果訪問就會丟擲錯誤。因此,在這執行流程進入作用域建立變數,到變數可以被訪問之間的這一段時間,就稱之為暫時死區。
簡單來說就是:如果區塊中存在 let 和 const 命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。假如我們嘗試在宣告前去使用這類變數,就會報錯
JS 和其他語言一樣,都要經歷編譯和執行階段。正是在這個短暫的編譯階段裡,JS 引擎會蒐集所有的變數宣告,並且提前讓宣告生效。至於剩下的語句,則需要等到執行階段、等到執行到具體的某一句的時候才會生效。這就是變數提升背後的機制。所以其實let
也有提升,使用es6
的引數初始化,引數的宣告都提升了,會提升的塊級作用域頂部,但是提升了卻沒有初始化,但是var
變數提升會初始化為undefined
,所以還可以使用,但是let
沒有初始化,所以在【提前的宣告】到【宣告初始化】的地方就是暫時性死區
,也就是不能在這區間使用這個提升的但沒有初始化let
變數