Javascript ECMAScript 2015:循环中的常量

Javascript ECMAScript 2015:循环中的常量,javascript,for-loop,scope,constants,ecmascript-6,Javascript,For Loop,Scope,Constants,Ecmascript 6,在完整的ECMAScript 2015实现中,下面的两个(或两者都没有/两者都没有)代码片段中的哪一个应该工作: for(常数a) for(常数i=0;i

在完整的ECMAScript 2015实现中,下面的两个(或两者都没有/两者都没有)代码片段中的哪一个应该工作:

for(常数a)

for(常数i=0;i

根据我的理解,第一个示例应该可以工作,因为
e
是为每个迭代初始化的。第二个版本中的
i
不也是这样吗


我很困惑,因为现有的实现(Babel、IE、Firefox、Chrome、ESLint)似乎并不一致,并且有一个完整的
const
实现,两个循环变量的各种行为;我也无法在标准中找到一个具体的点,因此这将是非常感谢的。

您的第二个示例肯定不起作用,因为
I
声明一次,而不是在每次迭代中,这只是循环类别如何工作的函数

您可以在常规浏览器中尝试此操作:

for (var i = 0, otherVar = ""; i < [1,2,3,4].length; i += 1){
  console.log(otherVar)
  otherVar = "If otherVar was initialized on each iteration, then you would never read me.";
}
这些是无效的:

for(const i = 0;;){ ++i; break; } 
for(const i = 0;;++i){ if(i > 0) break; }
我不知道为什么Firefox在阅读了ES2015规范后会出现语法错误(尽管我相信Mozilla的聪明人是正确的),但它似乎应该引起一个例外:

在环境记录中创建新的但未初始化的不可变绑定。字符串值N是绑定名称的文本。如果S为true,则无论引用该绑定的操作的严格模式设置如何,尝试在初始化绑定之前访问该绑定的值或在初始化后设置该绑定的值都会引发异常。S是一个可选参数,默认为false


您的第二个示例肯定不起作用,因为
i
只声明一次,而不是每次迭代都声明一次,这只是循环类别如何工作的函数

您可以在常规浏览器中尝试此操作:

for (var i = 0, otherVar = ""; i < [1,2,3,4].length; i += 1){
  console.log(otherVar)
  otherVar = "If otherVar was initialized on each iteration, then you would never read me.";
}
这些是无效的:

for(const i = 0;;){ ++i; break; } 
for(const i = 0;;++i){ if(i > 0) break; }
我不知道为什么Firefox在阅读了ES2015规范后会出现语法错误(尽管我相信Mozilla的聪明人是正确的),但它似乎应该引起一个例外:

在环境记录中创建新的但未初始化的不可变绑定。字符串值N是绑定名称的文本。如果S为true,则无论引用该绑定的操作的严格模式设置如何,尝试在初始化绑定之前访问该绑定的值或在初始化后设置该绑定的值都会引发异常。S是一个可选参数,默认为false


以下是循环工程的详细说明:

for (const e of a)
ES6规范将其描述为:

如需声明,请联系我们进行绑定

循环命令将不起作用:

for (const i = 0; i < a.length; i += 1)
for(常数i=0;i
这是因为在执行循环体之前只对声明求值一次


以下为循环的工作原理:

for (const e of a)
ES6规范将其描述为:

如需声明,请联系我们进行绑定

循环命令将不起作用:

for (const i = 0; i < a.length; i += 1)
for(常数i=0;i
这是因为在执行循环体之前只对声明求值一次


这次我不会引用规范,因为我认为通过示例更容易理解发生了什么

for(常数a).

基本相当于

{
    const __it = a[Symbol.iterator]();
    let __res;
    while ((__res = __it.next()) && !__res.done) {
        const e = __res.value;
        …
    }
}
为简单起见,我忽略了在
a
表达式中有一个带有
e
的TDZ,以及各种
\u it.return()
/
\u it.throw(e)
调用,以防循环过早退出(
break
throw

for(常数i=0;i

基本相当于

{
    const i = 0;
    while (i < a.length) {
        …
        i += 1;
    }
}
{
常数i=0;
while(i

,在
for
循环中的
const
声明不会在每次循环迭代中重新声明(并且初始化器也不会重新执行)。除非您在第一次迭代中
break
,否则您的
i+=
将抛出这里。

这次我不会引用规范,因为我认为通过示例更容易理解发生了什么

for(常数a).

基本相当于

{
    const __it = a[Symbol.iterator]();
    let __res;
    while ((__res = __it.next()) && !__res.done) {
        const e = __res.value;
        …
    }
}
为简单起见,我忽略了在
a
表达式中有一个带有
e
的TDZ,以及各种
\u it.return()
/
\u it.throw(e)
调用,以防循环过早退出(
break
throw

for(常数i=0;i

基本相当于

{
    const i = 0;
    while (i < a.length) {
        …
        i += 1;
    }
}
{
常数i=0;
while(i

,在
for
循环中的
const
声明不会在每次循环迭代中重新声明(并且初始化器也不会重新执行)。除非您在第一次迭代中
break
,否则您的
i+=
将在此处抛出。

const用于常量x.x,您应该使用letinstead@JamesThorpe不,我的问题只是想弄清楚这种行为应该是什么。例如,ESLint认为第一个示例是OK(并且使用
preference const
选项进行首选),第二个示例是无效的。大多数浏览器实现都认为这两个例子都是无效的。AFEK第一个OK是可以的,因为每次迭代都会重新初始化。它在Chrome中工作。@lyschoning,这不应该也适用于第二个示例?@adrianp肯定不是第二个示例。正则for循环本质上等价于
{const i=0;而(i
const用于常量x.x,您应该使用letinstead@JamesThorpe不,我的问题只是想弄清楚这种行为应该是什么。例如,ESLint认为第一个示例是OK(并且使用
preference const
选项进行首选),第二个示例是无效的。大多数浏览器实现