for (const e of a)
for (const i = 0; i < a.length; i += 1)
据我理解,第一个例子应该可以工作,因为
e
在每次迭代时都会被初始化。那么对于第二个版本,i
是否也是这种情况?我感到困惑,因为现有的实现(Babel,IE,Firefox,Chrome,ESLint)似乎并不一致,并且对于这两个循环变量有着不同的行为;同时我也无法找到标准中的具体说明,如果有的话,请提供,谢谢!
for (const e of a)
for (const i = 0; i < a.length; i += 1)
e
在每次迭代时都会被初始化。那么对于第二个版本,i
是否也是这种情况?for (const e of a)
ES6规范将其描述为:
ForDeclaration:LetOrConst ForBinding
命令式的for循环将无法工作:
for (const i = 0; i < a.length; i += 1)
这是因为在循环体执行之前,声明只被评估一次。
const...
不是一个表达式。你需要查看for(LexicalDeclaration Expression;Expression) Statement
的规则。 - Felix Klingconst
在每次迭代中不会被重新声明。 - Felix Klingfor (const e of a)
似乎无法工作。我收到了SyntaxError: invalid for/in left-hand side
的错误提示。 - Chris_Fconst
...?所以说,先声明 const a = 4
,然后再声明 const a = 6
是可以的吗?这根本不是常量! - Kokodoko这次我不会引用规范,因为我认为通过示例更容易理解发生了什么。
for (const e of a) …
基本上等同于
{
const __it = a[Symbol.iterator]();
let __res;
while ((__res = __it.next()) && !__res.done) {
const e = __res.value;
…
}
}
为简便起见,我忽略了表达式a
中的e
可能存在的TDZ问题以及在循环提前退出(例如break
或throw
)时,在体内调用的各种__it.return()
/__it.throw(e)
方法。
for (const i = 0; i < a.length; i += 1) …
基本上等同于
{
const i = 0;
while (i < a.length) {
…
i += 1;
}
}
与let
不同的是,在for
循环中,const
声明不会在每个循环迭代中重新声明(且初始化程序无论如何都不会被重新执行)。除非你在第一次迭代中break
,否则你的i +=
将会抛出异常。
const
具有类似于var
的作用域,并且在赋值时不会抛出异常。请使用严格模式。 - Bergi你的第二个例子肯定不会起作用,因为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
。只有会修改 const
的 for
循环是不被允许的。
以下是有效的示例:
for(const i = 0;;){ break }
for(const i = 0; i < 10;){ break; }
以下是无效的:
for(const i = 0;;){ ++i; break; }
for(const i = 0;;++i){ if(i > 0) break; }
const i
只声明一次,但 let i
不会?你的例子只展示了 var i
的工作原理,而不是 const i
。由于 var
、const
和 let
之间存在明显的区别,我认为引用关于 const
的规范将非常有价值。 - Felix Klingconst
值只能被赋值一次,任何尝试重新声明const
都不起作用。我的示例是为了证明声明仅发生一次,提问者理解const
的语义。let
不是问题,而且我没有明确表示您所暗示的意思,您误读了。 - Kit Sundelet
限制在迭代范围内并且禁止重新声明const。 在Firefox中运行此代码: function test(){console.log(“我将仅运行一次”);} for(let i = 1,_ = test();i <10; ++ i){console.log(i);}
- Kit Sundelet
,那么每次迭代都会得到自己的 i
的副本。for(let foo = 0; i < 10; ++i){}
等同于(funtion() { for(var i = 0; i < 10; ++i){ (function(i) { }(i)) } }());
我的理解是:let
和 const
都是块级作用域。对于 const
和 let
,for/in
和 for/of
暴露了相同的行为,但普通的 for
循环却没有。它在处理 const
时明显地表现不同(或许可以理解)。你简单地说它是“声明一次”,但我认为这样过于简化了。 - Felix Kling
prefer-const
选项下更受欢迎),而第二个示例无效。大多数浏览器实现都认为这两个示例都无效。 - adrianp{const i = 0; while(i < a.length) { /* for body */ i += 1}}
。 - lyschoening