在JavaScript中循环x次的典型方法是:

for (var i = 0; i < x; i++)
  doStuff(i);

但我不想使用++运算符或任何可变变量。那么在ES6中,是否有一种方法来循环x乘以另一种方法?我喜欢Ruby的机制:

x.times do |i|
  do_stuff(i)
end

JavaScript/ES6中有类似的吗?我可以欺骗自己的生成器:

function* times(x) {
  for (var i = 0; i < x; i++)
    yield i;
}

for (var i of times(5)) {
  console.log(i);
}

当然,我仍然在使用i++。至少它在视线之外:),但我希望在ES6中有更好的机制。


当前回答

如果你愿意使用库,也可以使用lodash _。Times或下划线_.times:

_.times(x, i => {
   return doStuff(i)
})

注意,这将返回一个结果数组,所以它更像这样的ruby:

x.times.map { |i|
  doStuff(i)
}

其他回答

Array(100).fill().map((_,i)=> console.log(i) );

这个版本满足了OP对不变性的要求。还要根据您的用例考虑使用reduce而不是map。

这也是一个选择,如果你不介意在你的原型中做一点改变的话。

Number.prototype.times = function(f) {
   return Array(this.valueOf()).fill().map((_,i)=>f(i));
};

现在我们可以这么做了

((3).times(i=>console.log(i)));

+1到arcseldon的.fill建议。

Afaik,在ES6中没有类似Ruby的times方法的机制。但是你可以通过使用递归来避免突变:

let times = (i, cb, l = i) => {
  if (i === 0) return;

  cb(l - i);
  times(i - 1, cb, l);
}

times(5, i => doStuff(i));

演示:http://jsbin.com/koyecovano/1/edit?js,控制台

在我看来,这个问题最正确的答案(这是有争议的)隐藏在Sasha Kondrashov的评论中,也是最简洁的,只用了两个字:“不”。没有比Ruby的语法更好的for循环替代函数了。我们可能希望有一个,但就是没有。

问题中没有明确说明,但我认为任何“循环N次”问题的解决方案都不应该分配内存,至少不与N成正比。这个标准将排除大多数“原生javascript”的答案。

其他答案显示了Ruby中的实现,这很好,除了这个问题显式地要求本机javascript解决方案。这个问题已经有了一个非常不错的手卷解决方案,可以说是最易读的解决方案之一。

这不是我要教的东西(或者在我的代码中使用),但这里有一个值得codegolf使用的解决方案,无需改变变量,不需要ES6:

Array.apply(null, {length: 10}).forEach(function(_, i){
    doStuff(i);
})

更像是一个有趣的概念证明,而不是一个有用的答案,真的。

for (let i of Array(100).keys()) {
    console.log(i)
}