提问人: 提问时间:11/3/2023 更新时间:11/3/2023 访问量:43
相同情况下的不同 Uncaught ReferenceError
Different Uncaught ReferenceError for same situations
问:
我不明白为什么在这些相同的情况下控制台会返回两个不同的输出
console.log(a);
let a = 1;
控制台显示 A 未定义
和这里
function a1() {
console.log(a);
let a = 1;
}
a1();
控制台显示初始化前无法访问“a” 在这两种情况下,它不应该返回“初始化前无法访问'a'”吗?因为我们使用 let 声明来声明变量,并且在这两种情况下它们都在 TDZ 中?为什么说 a 没有定义?
为什么会这样?在全局范围内提升变量与在块范围内提升变量是否不同?
答:
这只是您使用的控制台处理您粘贴到其中的内容的方式的结果。不要从中吸取任何教训,并在控制台之外应用它。控制台 REPL 执行的几项操作与代码的实际行为方式略有不同,无论是在全局范围还是在函数范围(或模块范围)上。控制台 REPL 在很多方面都很方便,但在没有仔细检查的情况下,不要推断它们对其他环境的作用。
在您的示例中,控制台评估了每个语句,而没有向前扫描到下一个语句(即使您将行粘贴在一起并在它们之间粘贴换行符也是如此)。因此,首先它进行了评估,并且由于没有声明的标识符,因此它为您提供了标准。然后它评估了你的console.log(a);
a
a is not defined
let a = 1;
但这并不是在全局范围内实际评估代码的方式。如果您有:
console.log(a);
let a = 1;
...JavaScript 引擎首先扫描所有代码,查找诸如 (and and and declarations) 之类的声明,然后为它们创建绑定(大致是变量)。现代声明 (, , ) 的绑定未初始化;旧式绑定 (, 声明) 被初始化(分别使用或与函数一起使用)。因此,当它去评估分步代码时,它会看到它已声明,但未初始化,并给出错误:let a
var a
function
class
let
const
class
var
var
function
undefined
a
Cannot access 'a' before initialization
console.log(a);
let a = 1;
当你使用一个函数时,它给了你第二个行为,因为该函数在完成之前不会被评估,并且评估的工作方式与我上面描述的全局评估类似,因此 JavaScript 引擎知道它已声明(但未初始化)并抛出相应的错误。a
评论
console.log(a)
let a = 1;
ReferenceError