最近我在Chrome控制台遇到了这个奇怪的事情。在这里,我故意为a分配一个未定义的东西,以便抛出错误。
let a = werwr // Uncaught ReferenceError: werwr is not defined
然后,当我尝试为a分配合法的东西时,发生了这种情况:
let a = "legit string" // Uncaught SyntaxError: Identifier 'a' has already been declared
因此我无法使用"让"因为已经宣布了。因此,我尝试将其他内容重新分配给"已经宣布为"
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
答案 0 :(得分:9)
当您将时间死区引入全局范围时会发生这种情况。如您所知,let
声明are hoisted but left uninitialised。由于控制流,可能会发生变量从未初始化:
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;
与功能范围相反,此处变量保持未初始化非常重要。全局范围永远持续,变量永远死亡。它不会也不会被初始化,并且不能重新声明词法变量(这有助于防止错误)。
这was discussed on es-discuss,但被视为无关紧要。如果顶级<script>
执行引发错误,则比未初始化的变量存在更大的问题。没有恢复的途径。如果你需要一个(例如,尝试在连续的脚本中重新声明它),你必须使用var
。
你在devtools控制台中遇到同样的问题有点麻烦,但可以作为特殊范围的控制台解决。
答案 1 :(得分:1)
你应该知道在JS中提升。基本上,这样的声明
let a = werwr;
被解释为
let a;
a = werwr;
这就是为什么在运行第二行代码时已经声明了。
<强>更新强>
因此,ES规范中有一个注释 https://tc39.github.io/ecma262/#prod-LetOrConst
let和const声明定义作用域的变量 运行执行上下文的LexicalEnvironment。变量是 当他们包含的词汇环境被实例化时创建但是 在变量的LexicalBinding之前,可能无法以任何方式访问 评价即可。由带有初始化程序的LexicalBinding定义的变量 被赋予其初始化程序的AssignmentExpression的值 评估LexicalBinding,而不是在创建变量时。如果 let声明中的LexicalBinding没有Initializer 在LexicalBinding中为变量赋值undefined 被评估。
...
&#34;但在评估变量&#34;&#34; 之前,可能无法以任何方式访问它
意味着,必须先成功完成声明才能访问变量(获取值,赋值,或执行typeof
或事件delete
);
在您的情况下,变量的LexicalBinding会被异常中断。
let a = werwr // Uncaught ReferenceError: werwr is not defined
请点击链接,了解更多相关信息。如果您找到了恢复变通a
的方法,请告诉我。
谢谢,今天我发现了一些关于Javascript的新内容。