暂时性死区
🍞暂时性死区
使用let或const声明的变量,在达到声明处之前都是无法访问的,试图访问会导致一个引用错误,即使在通常是安全的操作时(例如使用typeof运算符),也是如此。示例如下:
if (conditon){
console.log(typeof value); // 出现引用错误,无法找到声明的value变量
let value = "YES";
}
此处的value变量使用了let进行定义与初始化,但该语句永远不会被执行,因为声明之 前的那行代码抛出了一个错误。出现该问题是因为:value位于被JS社区称为暂时性死区 ( temporal dead zone,TDZ )的区域内。该名称并未在ECMAScript规范中被明确命名,但经常被用于描述let或const声明的变量为何在声明处之前无法被访问。本小节的内容涵盖了暂时性死区所导致的声明位置的微妙之处,尽管这里使用的都是let,但替换为const也会有相同情况。
当JS引擎检视接下来的代码块并发现变量声明时,它会在面对var的情况下将声明提升到函数或全局作用域的顶部,而面对let或const时会将声明放在暂时性死区内。任何在暂时性死区内访问变量的企图都会导致“运行时”错误( runtime error )。只有执行到变量的声明语句时,该变量才会从暂时性死区内被移除并可以安全使用。
使用let或const声明的变量,若试图在定义位置之前使用它,无论如何都不能避免暂时性死区。而且正如上例所演示的,这甚至影响了通常安全的typeof运算符。然而,你可以在变量被定义的代码块之外对该变量使typeof,尽管其结果可能并非预期。考虑以下代码:
console.log(typeof value); // 会出现"undefined"
if (condition){
let value = "blue";
}
当typeof运算符被使用时,value并没有在暂时性死区内,因为这发生在定义value变 量的代码块外部。这意味着此时并没有绑定value变量,而typeof仅单纯返回了"undefined"。
暂时性死区只是块级绑定的一个独特表现,而另一个独特表现则是在循环时使用它。(可以观看下节循环中的块级绑定)