una*_*ist 3 javascript for-loop ecmascript-6
首先,let
可用于循环计数器声明。这也在MDN 中进行了描述。
for(let i = 0; i < 2; ++i) {
setTimeout(function(){
document.write(i + "<br>");
}, 0);
}
Run Code Online (Sandbox Code Playgroud)
结果:
0
1
Run Code Online (Sandbox Code Playgroud)
由于let
使用了,i
可以在for
块内部更改值。
for(let i = 0; i < 2; ++i) {
setTimeout(function(){
document.write(i + "<br>");
}, 0);
i = 123; // I want to block this assignment!!
}
Run Code Online (Sandbox Code Playgroud)
所以我考虑使用const
而不是let
.
for(const i = 0; i < 2; ++i) { // throws Assignment to constant variable
setTimeout(function(){
document.write(i + "<br>");
}, 0);
i = 123; // not here...
}
Run Code Online (Sandbox Code Playgroud)
但是,此代码会抛出Assignment to constant variable.
(在 Chrome 53.0.2773.0 中)。
我希望这个循环像第一个let
例子一样循环两次,但i
只在内部 for 循环迭代中使计数器可写。
我认为这是允许的,因为ECMA-262 §13.7.4.7似乎提到了这种情况,因为If isConst is true, ...,但我在 MDN 和其他站点中找不到这种用法(或实现状态)。Kangax 的表包含针对let
bindings 的测试,但不包含针对bindings 的测试const
。
我测试了它(在 Firefox 中)并且 const 绑定根据规范工作:
let i = 0;
for (const len = 3; i < len; i++) {
console.log(i);
}
// From https://kangax.github.io/compat-table/es6/#test-const
for (const baz = 0; false;) {}
// Yay, a const counter! ...uh
for (const counter = {i: 0}; counter.i < 3; counter.i++) {
console.log(counter.i);
}
Run Code Online (Sandbox Code Playgroud)
虽然它可能不是特别有用...
为什么有效? 该标准指出:
5. For each element dn of boundNames do
a. If isConst is true, then
i. Perform loopEnv.CreateImmutableBinding(dn, true).
Run Code Online (Sandbox Code Playgroud)
...whereboundNames
指的是const
绑定。正如您所看到的,该标准允许const
“循环计数器”,但并没有说您以后可以重新分配(增加)它们(实际上,这不起作用)。