暂时性死区
🍞暂时性死区
使用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"
。
暂时性死区只是块级绑定的一个独特表现,而另一个独特表现则是在循环时使用它。(可以观看下节循环中的块级绑定)