'让'覆盖一个全局声明并抛出一个ReferenceError? [英] Does 'let' override a global declaration and throws a ReferenceError?

查看:187
本文介绍了'让'覆盖一个全局声明并抛出一个ReferenceError?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在浏览 var let 文档示例之间的区别,并测试当未声明变量被调用时,全局范围自动为其提供声明(这就是为什么以下代码段不会在任何变量中引发错误):



  x = 3; console.log(x);(function(){y = x + 39;})()console.log(y);  



但是,当一个变量用 code>在相同的全局范围内分配:



  x = 3; let x = 42; console.log(x) / code> 



抛出以下错误之一:


ReferenceError x 未定义(Chromium)



ReferenceError :在初始化(Firefox)之前不能访问词汇声明 x

我明白 let 不允许 x to 起重机,但由于以前引用(意味着从全球范围自动声明)不应在这种情况下重新声明发生?


SyntaxError :标识符 x 已被声明


因此上面的错误抛出?



我也明白,在 严格模式 第一个代码段将引发 ReferenceError ,所以这意味着 let 强制这个特定的严格模式规则(所有变量需要被声明)在全局范围?

解决方案

你对,这是奇怪的行为。它给出这些错误的原因是因为它认为您尝试将值 3 分配给您的 let 变量的全球价值。正如其他人所提到的那样,这导致了起重时间的死区问题。


变量是在包含词汇环境为
时创建的


- 在实例化但之前, 来源



此代码显示了放置代码导致TDZ的位置:

  //在控制流评估之前访问x `let x`语句
//会引发由于TDZ引起的ReferenceError。
// console.log(x);

let x = 42;
//从这里开始,访问`x`是非常好的!
console.log(x);

-



你可以看到包装 let 在自己的块块内修复它:

  x = 3; 
{
let x = 42;
console.log(x); // 42
}

或者,您可以在 window object:

  window.x = 3; 

let x = 42;
console.log(x); // 42


I was going through the Difference between var and let documentation example and was testing that when an undeclared variable is invoked, the global scope automatically provides a declaration for it (that's why the following snippet does not throw an error in any of the variables):

x = 3;
console.log(x);

(function() {
  y=x+39;
})()
console.log(y);

However, when one variable is declared with let after the assignment in the same global scope:

x=3;
let x = 42;
console.log(x);

One of the following errors is thrown:

ReferenceError: x is not defined (Chromium)

ReferenceError: can't access lexical declaration x before initialization (Firefox)

I understand that let does not allow x to hoist, but since it was previously referenced (implying an automatic declaration from the global scope) shouldn't in this case a re-declaration happen?

SyntaxError: Identifierx has already been declared

And therefore the error above thrown?

I also understand that in strict mode the first snippet would throw a ReferenceError, so does this mean that let forces this particular rule of strict mode (all variables need to be declared) upon the global scope?

解决方案

You're right, it's weird behavior. The reason it's giving those errors is because it thinks you're trying to assign the value 3 to your let variable instead of the global value. As others mentioned, this leads to the temporal deadzone issue with hoisting.

The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated

- Source

This code shows where placing code causes the TDZ:

// Accessing `x` here before control flow evaluates the `let x` statement
// would throw a ReferenceError due to TDZ.
// console.log(x);

let x = 42;
// From here on, accessing `x` is perfectly fine!
console.log(x);

- Source

You can see that wrapping the let inside its own block block fixes it:

x=3;
{
let x = 42;
console.log(x); // 42
}

Alternatively, you can define the global explicitly on the window object:

window.x=3;

let x = 42;
console.log(x);  // 42

这篇关于'让'覆盖一个全局声明并抛出一个ReferenceError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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