Chrome 控制台已声明变量为 let 抛出未定义的引用错误 [英] Chrome console already declared variables throw undefined reference errors for let

查看:14
本文介绍了Chrome 控制台已声明变量为 let 抛出未定义的引用错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我在 chrome 控制台中遇到了这个奇怪的事情.这里我故意将一个未定义的东西分配给 a 以便抛出错误.

Recently I ran into this weird thing in chrome console. Here I am intentionally assigning an undefined thing to a in order to throw an error.

let a = werwr // Uncaught ReferenceError: werwr is not defined

然后当我试图将合法的东西分配给 a 时,发生了这种情况:

Then when I tried to assign something legit to a, this happened:

let a = "legit string"   // Uncaught SyntaxError: Identifier 'a' has already been declared

所以我不能使用let",因为 a 已经被声明了.所以我试图将别的东西重新分配给已经声明的"

so I can't use "let" because a has already been declared. So I tried to reassign something else to the "already declared a"

a = "legit string"   //  Uncaught ReferenceError: a is not defined

所以似乎我不能将其他东西重新分配给 a 但同时, a 已被声明,所以我不能再次使用 let .

So it seems like I can't reassign something else to a but at the same time, a has been declared so I can't use let again.

我理解声明和分配变量之间的区别.然而,在这里似乎两者都不能再做.这与控制台中让"的范围有关吗?因为同样的事情完全适用于var"

I understand the difference between declaring and assigning a variable. However here it seems that neither could be done again. Does this has something to do with the scope of "let" in console? Because the same thing totally works for "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 语句与隐式案例之间似乎存在一些差异.

There seem to be some difference between "manually" hoisting the let statement vs the implicit case.

throw new Error
let example = 5
// same errors as before

虽然在这种情况下示例可以再次重新分配.

while in this case example can be reassigned again.

let example
throw new Error
example = 5

推荐答案

当您将时间死区引入全局范围时会发生这种情况.如您所知,let 声明被提升但未初始化.由于控制流的原因,可能会发生一个变量从未被初始化的情况:

This happens when you introduce the temporal dead zone to the global scope. As you might know, let declarations are hoisted but left uninitialised. Due to control flow, it can happen that a variable is never initialised:

function …() {
    if (false)
        example; // would throw a ReferenceError if it was evaluated
    … // do something
    if (true)
        return; // stop!
    let example = 5; // never executed
}

这在函数范围内很好.也许出了问题,也许根本不需要该变量 - 在下一次调用中,将创建一个带有新变量的新作用域.

This is fine in a function scope. Maybe something went wrong, maybe the variable wasn't needed at all - in the next call, a new scope with a new variable will be created.

类似的事情可能发生在全局范围内,当你在变量初始化之前抛出一个异常(这里只有异常作为控制流结构起作用,没有其他方法能达到同样的效果).

A similar thing can happen in the global scope, when you throw an exception before the variable is initialised (only exceptions work here as a control flow construct, nothing else achieves the same effect).

throw new Error;
let example = 5;

与函数作用域相反,变量保持未初始化在这里确实很重要.全局作用域永远存在,而变量永远死了.它没有也永远不会被初始化,并且词法变量不能被重新声明(这有助于防止错误).

In contrast to the function scope, it does matter here that the variable stays uninitialised. The global scope lasts forever, and the variable is eternally dead. It was not and will never be initialised, and lexical variables cannot be re-declared (which helps preventing mistakes).

这个在es-discuss,但被视为无关紧要.如果顶级 <script> 执行抛出错误,那么您遇到的问题比未初始化的变量要大.没有办法恢复.如果您需要一个(例如,通过尝试在连续的脚本中重新声明它),您无论如何都必须使用 var.

This was discussed on es-discuss, but deemed irrelevant. If top-level <script> execution throws an error, you have bigger problems than uninitialised variables. There is no path to recover. If you need one (e.g. by trying to re-declare it in successive scripts), you have to use var anyway.

您在 devtools 控制台中遇到同样的问题有点麻烦,但可以将控制台作为特殊范围来解决.

That you have the same problem in the devtools console is a bit of a nuisance, but could be solved for the console as a special scope.

这篇关于Chrome 控制台已声明变量为 let 抛出未定义的引用错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆