var a = 6;
{
console.log(a)
let a =55
}
当我执行此代码段时,我收到以下错误消息: 引用错误:初始化前无法访问"a">
为什么控制台.log(a) 没有给出 6 作为结果。
你的问题的答案在你的标题中:变量位于"时间盲区",这只是你所看到的行为的名称。
在 MDN 上拿这个解释:
与用
var
声明的变量不同,let
变量将以值 undefined 开头,在计算其定义之前不会初始化。在初始化之前访问变量会导致ReferenceError
。变量从块开始到初始化被处理都处于"时间死区"。
区块的开始是开场{
,你的console.log(a)
在语句之前let
,所以它在这个"死区"。
为什么会这样工作?因为它可以帮助程序员检测代码中的错误,这些错误是由于不同范围内具有相同名称的变量之间的混淆而导致的。
嵌套块将创建一个新的块范围的词法环境。
内部a
变量在该作用域中声明,但在初始化之前访问,因此会出现错误。
声明let a
内部作用域覆盖var a
声明,因此它是一个不同的变量,就像您是这样编写的一样:
var a = 6;
{
console.log(a2)
let a2 =55
}
.
为了补充上述两个答案,语句let a = 55
实际上是两个语句合二为一:let a
- 声明 - 和a = 55
- 赋值。由于Javascript的提升规则,声明在进入块时被处理,但赋值保留其词汇位置。
所以块:
var a = 6
{
console.log(a)
let a = 55
}
在语义上等效于:
var a = 6
{
let a
console.log(a)
a = 55
}
由于a
的本地声明掩盖了同名的全局变量,因此在执行console.log(a)
时a
已声明但尚未赋值。