暂时性死区TDZ理解与总结
為什么會出現暫時性死區?
先來看看 ES6 標準中對 let/const 聲明中的解釋 第13章,有如下一段文字:The variables are createdwhentheir containing Lexical Environmentisinstantiated but maynotbe accessedinany wayuntilthevariable’s LexicalBindingisevaluated.
當然這段話我看完也很懵,查閱了一些帖子,翻譯成人話就是:
當程序的控制流程在新的作用域(module function 或 block 作用域)進行實例化時,在此作用域中用let/const聲明的變量會先在作用域中被創建出來,但因此時還未進行詞法綁定,所以是不能被訪問的,如果訪問就會拋出錯誤。因此,在這運行流程進入作用域創建變量,到變量可以被訪問之間的這一段時間,就稱之為暫時死區。
如果你還是記不住,那么只需理解下面這句話即可:
ES6規定,let/const 命令會使區塊形成封閉的作用域。若在聲明之前使用變量,就會報錯。總之,在代碼塊內,使用 let 命令聲明變量之前,該變量都是不可用的。這在語法上,稱為 “暫時性死區”( temporal dead zone,簡稱 TDZ)。
if (true) {
// TDZ開始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
上面代碼中,在let命令聲明變量tmp之前,都屬于變量tmp的“死區”。“暫時性死區”也意味著typeof不再是一個百分之百安全的操作。
typeof x; // ReferenceError let x;
上面代碼中,變量x使用let命令聲明,所以在聲明之前,都屬于x的“死區”,只要用到該變量就會報錯。因此,typeof運行時就會拋出一個ReferenceError。大家應該養成良好的編程習慣,變量一定要在聲明之后使用,否則就報錯。
有些“死區”比較隱蔽,不太容易發現。
function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 報錯
上面代碼中,調用bar函數之所以報錯,是因為參數x默認值等于另一個參數y,而此時y還沒有聲明,屬于”死區“。如果y的默認值是x,就不會報錯,因為此時x已經聲明了。
ES6規定暫時性死區和let、const語句不出現變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為。這樣的錯誤在ES5是很常見的,現在有了這種規定,避免此類錯誤就很容易了。
總之,暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現,才可以獲取和使用該變量。
我們再來看一個問題
function bar() {
var x = y
y = 2
return [x, y];
}
bar() // y未定義
function bar() {
var x = 2
y = 2
return [x, y];
}
bar()
window.y // 2
至于上面的y未定義的錯,也是一個死區。千萬不要以為下面隱式聲明的一個全局變量就以為y會變量提升,不是這樣的。只有var聲明的才會提升,隱式的全局變量是不會提升的,這樣就會存在死區。
總結
以上是生活随笔為你收集整理的暂时性死区TDZ理解与总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot的端口配置serve
- 下一篇: SpringBoot的配置优先级,一个具