【问题标题】:Redeclaration with var works but not with let in Chrome Snippets使用 var 重新声明有效,但不适用于 Chrome 代码段中的 let
【发布时间】:2020-11-04 18:22:34
【问题描述】:

我开始学习 JavaScript,我在 Google Chrome 中使用 Snippets 或控制台。我不明白一件事。 当我运行 sn-p 时:

let x = 5;
console.log(x);

多次。一切都很好,但是当我第一次运行时:

var x = 5;
console.log(x);

然后我将代码更改为使用 let:

let x = 5;
console.log(x);

我收到错误SyntaxError: Identifier 'x' has already been declared,我不明白为什么。 我假设用 let 声明的变量在某种程度上是“易失的”,但用 var 声明的变量与窗口对象相关联,所以它们是“非易失的”? 或者更一般地说:脚本执行后全局环境的声明性环境记录中的声明是否被清除,但存储在全局环境的对象环境记录中的声明不是? 当我在 Google Chrome Snippets/Console 中多次运行 sn-p 时,它是在相同的执行上下文中运行,还是每次按下运行按钮时都使用新的全局环境重新创建?

【问题讨论】:

  • 那是因为当您执行let x = 5 时,您无法再次重新声明变量(因为您提到您多次执行此操作),即稍后let x = ...。相反,您需要重新分配其值,即x = ...
  • @Terry 实际上,如果我只使用 let 进行声明,我可以毫无问题地运行脚本。仅当我第一次使用 var 然后将其更改为 let 时才会出现问题。示例是完整的 - 它们是 2 行代码。代码中没有重新声明。
  • @swch 如果您不止一次编写let x = 5 并运行代码,但它不会工作。这是 Chrome (V8) 控制台的一些特定优化。 Firefox 控制台抛出错误。 developers.google.com/web/updates/2019/12/…
  • 将代码复制到控制台时,将其包装在 IIFE 中。这样,您在多次复制时就不必担心重新声明。

标签: javascript ecmascript-6 let executioncontext


【解决方案1】:

您使用的是哪个 Chrome 版本? Since Chrome 80 you can redeclare let variables 在浏览器控制台中。但请记住,这只存在于测试目的。真正的 JavaScript 引擎(Node.js、除 DevTools 之外的 Chrome 等)仍然会抛出错误。

var 可以重新声明是正常的,因为它的作用域不同。这是让 ES6 添加的原因之一。您可以阅读有关 var 与 let here 的更多信息。

【讨论】:

  • Chrome 83,正如我提到的,运行脚本没有问题,只让。问题是在某些脚本中有 var 然后我将其更改为 let
  • 谢谢,这让我了解了这种奇怪的行为......你知道我们是否可以禁用它吗?
【解决方案2】:

您可以将所有代码括在括号中。

{
let x = 5;
console.log(x);
}

JavaScript 允许您将任何代码包装在括号中。 每次运行 sn-p 时,括号将为您的 let 变量创建一个唯一的范围。

【讨论】:

    【解决方案3】:

    同一作用域内同一var 变量的多个声明将被忽略。 let(以及const)的情况并非如此,因为同一范围内的多个声明不会被忽略,从而导致第二个声明失败。

    考虑以下几点:

    var x = 1;
    var x = 2;
    

    以及以下内容:

    let x = 1;
    let x = 2;
    

    在第一个示例中,解释器将代码视为:

    var x;
    x = 1;
    x = 2;
    

    由于let 关键字,秒示例保持不变。

    虽然所有变量都在技术上被提升,但它们的评估方式并不相同。 来自https://www.ecma-international.org/ecma-262/9.0/index.html#sec-let-and-const-declarations

    var 语句声明了作用域为正在运行的变量 执行上下文的变量环境。 var 变量被创建 当它们包含的词法环境被实例化并且是 创建时初始化为未定义。

    意思是var 声明在其上下文被实例化后被评估。 但是,let 仅在达到代码中的声明后才被评估。

    【讨论】:

    猜你喜欢
    • 2017-05-30
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多