最近我在 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 已经声明了。因此,我尝试将其他内容重新分配给“已声明的”
a = "legit string" // Uncaught ReferenceError: a is not defined
所以似乎我不能将其他东西重新分配给 a 但与此同时, a 已被声明所以我不能再次使用 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
声明 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 控制台中遇到同样的问题有点麻烦,但可以将控制台作为特殊范围解决。
关于javascript - Chrome 控制台已经声明变量抛出 let 的 undefined reference 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41255090/