let 关键字的问题

5
我是一名有用的助手,可以为您进行文本翻译。以下是您需要翻译的内容:

我在编写一些代码时遇到了一个情况,我无法确定为什么 let 关键字会产生某种行为。

以下是相关的代码块:

var x = 20; // global scope

function f() {
  let x = x || 30;
}

f(); // VM3426:1 Uncaught ReferenceError: x is not defined(…)

我在执行f()时遇到了“x未定义”的错误。我知道let变量不会被提升,但由于'x'有一个全局副本,为什么函数'f'内的行不会默认使用全局副本而是抛出一个错误呢? 是否因为hoisting的原因,'let'将变量设置为未声明的状态(而不是var的'undefined')在函数开始时? 有没有办法在函数内获取'x'的全局副本?

1
本地变量 x 的声明遮蔽了全局变量,但由于您正在基于现有的 x 分配一个值,编译器无法找到一个,因为其中一个被遮蔽而另一个还没有被声明。 - Pablo Lozano
4个回答

5
异常是关于右侧的x - 当您初始化块范围的x变量时,全局变量已被“遗忘”,但新变量尚未声明,不能在初始化期间使用。
与显式调用全局变量进行比较。
    function f() {
      let x = window.x || 30;
    }

此外,还可以参考关于let死区的这篇MDN文章


1
所以你的意思是,首先评估这部分 let x 并创建局部变量 x 但不声明(以便遮蔽全局变量 x),然后执行这部分 x || 30,但找不到 x - Max Koretskyi
是的,没错 - 就是这样发生的。 - m.antkowicz
谢谢,我想知道这个“已创建但未声明”的过程叫什么。 - Max Koretskyi
我认为更可能的是全局名称从作用域中被删除 - 还没有创建任何东西。 - m.antkowicz

0

let 允许您声明变量,其作用范围仅限于使用它的块、语句或表达式。这与 var 关键字不同,后者定义了一个全局变量,或者在整个函数中本地定义,而不考虑块作用域。

在您的情况下,由于您正在使用相同的名称定义 let,因此会引发异常。

更多信息


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Alexander Derck

0

本地变量x的声明遮蔽了全局变量,新变量仍未首先声明,因此在初始化期间无法使用。这种情况与以下情况相同:

 var foo = 5;
    function do_something() {
      console.log(foo); // ReferenceError
      let foo = 2;
    }
  do_something();

参考资料 MDN

根据 @m.antkowicz 建议,您可以在您的情况下使用 window.x


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接