【问题标题】:ES6 why can I reassign a constant when defined in a loopES6为什么在循环中定义时可以重新分配常量
【发布时间】:2015-02-05 12:46:25
【问题描述】:

我正在玩一些毫无意义的逻辑来更好地理解 ES6,并且在定义常量时注意到了一个奇怪的现象。

在循环中定义时似乎可以更改常量赋值:

        "use strict";

        for(const i=0;i<10;i++){ //seting constant in loop
            console.log(i); //is reassigned and incremented 0,1,2,3...
        }


        const e = 0; //setting constant outside loop
        for(;e<10;e++){ //cannot reassign constant
            console.log(e);
        }

这是预期的行为吗?谁能解释为什么会发生这种情况,循环中的声明是否不同?


Statements/const更新

这个声明创建了一个常量,它可以是全局的,也可以是局部的 声明它的函数。常量是块范围的。

【问题讨论】:

  • 哇,刚刚在 Chrome 版本 40.0.2214.94 上尝试过这个,它会生成一个无限循环,可能是因为该常量从未被静音。你用的是哪个浏览器?
  • 这可能意味着 chrome 通过不重新分配它来使其正确(?但可能会抛出错误)并且仍然提升常量。在您的情况下,const 的行为似乎类似于 let developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 在 Firefox 中我得到TypeError: redeclaration of var i 作为第一个例子
  • @BenjaminBlonde 我使用的是canary v42,如果你包含"use strict";,它不会创建无限循环并且会递增

标签: javascript ecmascript-6


【解决方案1】:

当你修改“不可变绑定”时,current draft 只会在严格模式下抛出:

正如@kangax 指出的那样,重新分配常量应该总是抛出,因为const 创建了一个“不可变绑定”,并带有strict 标志(here):

如果 d 的 IsConstantDeclaration 为真,则

调用 env 的 CreateImmutableBinding 具体方法,传递 dn 和 true 作为参数。

then:

SetMutableBinding (N,V,S) ...

  1. 否则,如果 envRec 中 N 的绑定是可变绑定,则将其绑定值更改为 V。
  2. 否则,这必须是尝试更改不可变绑定的值,因此如果 S 为真,则抛出 TypeError 异常。

然而,节点只在严格模式下抛出:

"use strict";

const e = 0;
e = 42;  // SyntaxError: Assignment to constant variable.

(不清楚为什么这是“语法错误”)...

在非严格模式下,对常量的赋值会被静默忽略:

const e = 0;
e = 42;
console.log(e); // 0

使用带有 --harmony 标志的节点 v0.10.35 进行测试。

【讨论】:

  • 这看起来像是 Node.js 中的一个错误。或者没有实施。无论模式如何,重新分配给const 都应该抛出。如果您查看people.mozilla.org/~jorendorff/…,您会看到const 的结果是CreateImmutableBinding,其中S=true,所以一旦循环开始第二次迭代,就会出现TypeError。
  • 您还可以在我们的兼容表中看到确切的支持细分 — kangax.github.io/compat-table/es6/#const — 这表明目前 Chrome 中实际上缺少“重新定义 const 是一个错误”(这就是 OP体验,我猜)
  • 可以确认这看起来像是一个特定于 chrome 的问题,我在其他浏览器中没有遇到它
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
相关资源
最近更新 更多