Chrome控制台已声明变量为let发出未定义的引用错误

wha*_*les 12 javascript scope let google-chrome-devtools ecmascript-6

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

let a = werwr // Uncaught ReferenceError: werwr is not defined
Run Code Online (Sandbox Code Playgroud)

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

let a = "legit string"   // Uncaught SyntaxError: Identifier 'a' has already been declared
Run Code Online (Sandbox Code Playgroud)

所以我不能使用"let",因为已经声明了.所以我试图将其他东西重新分配给"已经宣布为"

a = "legit string"   //  Uncaught ReferenceError: a is not defined
Run Code Online (Sandbox Code Playgroud)

所以我似乎无法将其他内容重新分配给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
Run Code Online (Sandbox Code Playgroud)

跟进

"手动"提升let语句与隐式大小写之间似乎存在一些差异.

throw new Error
let example = 5
// same errors as before
Run Code Online (Sandbox Code Playgroud)

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

let example
throw new Error
example = 5
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 10

将时间死区引入全局范围时会发生这种情况.正如您可能知道的那样,let声明被悬挂但没有初始化.由于控制流,可能会发生变量从未初始化:

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

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

类似的事情可能发生在全局范围内,当你在变量初始化之前抛出异常时(只有例外在这里作为控制流构造工作,没有其他任何东西达到相同的效果).

throw new Error;
let example = 5;
Run Code Online (Sandbox Code Playgroud)

与函数范围相反,这里变量保持未初始化是很重要的.全局范围永远持续,变量永远死亡.它不是也不会被初始化,并且词法变量不能被重新声明(这有助于防止错误).

在es-discuss上讨论过,但被认为是无关紧要的.如果顶级<script>执行引发错误,则比未初始化的变量存在更大的问题.没有恢复的途径.如果你需要一个(例如通过尝试在连续的脚本中重新声明它),你必须使用它var.

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