问题描述
var a = 6;
{
console.log(a)
let a =55
}
执行此代码段时,出现以下错误消息: ReferenceError:初始化前无法访问“ a”
为什么console.log(a)没有给出6作为结果。
解决方法
嵌套的块将创建一个新的块作用域词汇环境。
在该范围内声明了内部a
变量,但在初始化之前对其进行了访问,因此出错。
内部作用域let a
声明将覆盖var a
声明,因此它是一个不同的变量,就像您这样编写:
var a = 6;
{
console.log(a2)
let a2 =55
}
。
,问题的答案在标题中:变量位于“临时死区”中,这只是您所看到的行为的名称。
与用
var
声明的变量将以undefined值开头的变量不同,let
变量在确定其定义之前不会被初始化。在初始化之前访问变量将导致ReferenceError
。该变量从程序段的开始一直处在“临时死区”中,直到初始化完成为止。
该块的开头是开头{
,而您的console.log(a)
在let
语句之前,因此它位于此“死区”。
为什么这样工作?因为它可以帮助程序员检测由于不同作用域中具有相同名称的变量之间的混淆而导致的代码错误。
,要添加到以上两个答案中,语句let a = 55
实际上是两个语句合而为一:let a
-一个声明-和a = 55
-一个赋值。由于Java的吊装规则,声明在进入块时进行处理,但赋值保留其词法位置。
所以块:
var a = 6
{
console.log(a)
let a = 55
}
在语义上等同于:
var a = 6
{
let a
console.log(a)
a = 55
}
由于a
的局部声明会掩盖同名的全局变量,因此在执行console.log(a)
时,a
已声明但尚未分配值。