Javascript ES6如何“让”在for循环迭代定义中在场景后面工作

时间:2017-06-14 12:48:31

标签: javascript ecmascript-6

提倡let语句在for循环中用作替换var迭代变量的声明。

通过使用let,用户可以放弃使用立即调用功能 例如,为回调保留迭代变量的值。

来自mdn

var list = document.getElementById('list');

for (let i = 1; i <= 5; i++) {
  let item = document.createElement('li');
  item.appendChild(document.createTextNode('Item ' + i));

  item.onclick = function(ev) {
    console.log('Item ' + i + ' is clicked.');
  };
  list.appendChild(item);
}

// to achieve the same effect with 'var'
// you have to create a different context
// using a closure to preserve the value
for (var i = 1; i <= 5; i++) {
  var item = document.createElement('li');
  item.appendChild(document.createTextNode('Item ' + i));

    (function(i){
        item.onclick = function(ev) {
            console.log('Item ' + i + ' is clicked.');
        };
    })(i);
  list.appendChild(item);
}

如果我在循环结束时更新迭代变量ifor结构将拾取它并在循环的comperator逻辑中使用新值并将该值传递给下一次执行该块。

console.log("start");
for (let i = 0; i < 5; i++) {
    console.log("in loop", i);
    setTimeout(function () {           
      console.log(i);
    }, 0);
    i = i + 2;

}
console.log("end");

结果:

start
in loop 0
in loop 3
end
undefined
2
5

第二次迭代中的更改,不会传播到第一次迭代超时回调。

目前,for循环实现为每次迭代创建一个块执行上下文,将迭代变量作为参数传递,并在块执行结束后专门提取其值并在{{1下一次迭代的机制。但知道这是否属实以及如何实施将会很有趣。

1 个答案:

答案 0 :(得分:1)

没有太多可说的。你的观察是正确的。每次迭代都有一个单独的块。所以,无论你的超时有多长,你都会看到相同的结果。

在每次迭代结束时,i的值将传递给下一次迭代。由于i不是对象,因此不会通过引用传递。因此,在下一次迭代中i的修改/增量不会影响前一次迭代块中i的值。

只是为了好玩,尝试使用对象而不是原始数字:

console.log("start");
for (let i = {i:0}; i.i < 5; i.i++) {
    console.log("in loop", i.i);
    setTimeout(function () {           
      console.log(i.i);
    }, 0);
    i.i = i.i + 2;

}
console.log("end");

结果:

start
in loop 0
in loop 3
end
undefined
6
6

如您所见,在这种情况下,您的i.i变量实际上将通过引用传递,因此您可以在不同的迭代块上修改它。