最近我在chrome控制台遇到了这个奇怪的事情。在这里,我故意为a分配一个未定义的东西,以便抛出错误。
let a = werwr // Uncaught ReferenceError: werwr is not defined
然后,当我尝试为a分配合法的东西时,发生了这种情况:
let a = "legit string" // Uncaught SyntaxError: Identifier 'a' has already been declared
所以我不能使用“let”,因为已经声明了。所以我试图将其他东西重新分配给“已经宣布为”
a = "legit string" // Uncaught ReferenceError: a is not defined
因此,我似乎无法将其他内容重新分配给a,但与此同时,a已被声明,因此我不能再使用let。
我理解声明和赋值变量之间的区别。然而,似乎这两者都不能再做了。这是否与控制台中“let”的范围有关?因为同样的事情完全适用于“var”
var a = werwr
// Uncaught ReferenceError: werwr is not defined
a = ”legit string“
// ”legit string“
var a = "legit string"
// Uncaught SyntaxError: Identifier 'a' has already been declared
跟进
“手动”提升let语句与隐式大小写之间似乎存在一些差异。
throw new Error
let example = 5
// same errors as before
而在这种情况下,可以再次重新分配示例。
let example
throw new Error
example = 5
将时间死区引入全局范围时会发生这种情况。你可能知道, let
声明 被悬挂但尚未初始化。由于控制流,可能会发生变量从未初始化:
function …() {
if (false)
example; // would throw a ReferenceError if it was evaluated
… // do something
if (true)
return; // stop!
let example = 5; // never executed
}
这在功能范围内很好。也许出了点问题,也许根本不需要变量 - 在下一次调用中,将创建一个带有新变量的新范围。
类似的事情可能发生在全局范围内,当你在变量初始化之前抛出一个异常时(只有异常在这里作为控制流构造工作,没有其他任何东西达到相同的效果)。
throw new Error;
let example = 5;
与函数范围相反,这里变量保持未初始化非常重要。全局范围永远持续,变量是 永远死了。它不是也不会被初始化,并且词法变量不能被重新声明(这有助于防止错误)。
这个 在讨论中进行了讨论,但被视为无关紧要。如果顶级 <script>
执行会抛出错误,你比未初始化的变量有更大的问题。没有恢复的途径。如果你需要一个(例如通过尝试在连续的脚本中重新声明它),你必须使用 var
无论如何。
你在devtools控制台中遇到同样的问题有点令人讨厌,但可以作为一个特殊的范围解决控制台问题。
你应该知道在JS中提升。基本上,这样的声明
let a = werwr;
被解释为
let a;
a = werwr;
这就是为什么在运行第二行代码时已经声明了。
UPDATE
因此,ES规范中有一个注释
https://tc39.github.io/ecma262/#prod-LetOrConst
let和const声明定义作用域的变量
运行执行上下文的LexicalEnvironment。变量是
在实例化包含词汇环境时创建 但
在变量的LexicalBinding之前,可能无法以任何方式访问它
评估。由带有初始化程序的LexicalBinding定义的变量
被赋值为Initializer的AssignmentExpression的值
评估LexicalBinding,而不是在创建变量时。如果
let声明中的LexicalBinding没有Initializer
在LexicalBinding中为变量赋值undefined
被评估。
...
“但在评估变量的LexicalBinding之前,可能无法以任何方式访问”
意味着,必须先成功完成声明才能访问变量(获取值,赋值或执行操作) typeof
或事件 delete
);
在您的情况下,变量的LexicalBinding由异常中断。
let a = werwr // Uncaught ReferenceError: werwr is not defined
请点击链接,了解更多相关信息。如果你找到了恢复变种的方法 a
, 请告诉我。
谢谢,今天我发现了一些关于Javascript的新内容。