在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中有更好的机制。


当前回答

发电机吗?递归?为什么这么讨厌突变?: -)

如果它是可以接受的,只要我们“隐藏”它,那么只要接受一元操作符的使用,我们就可以让事情变得简单:

Number.prototype.times = function(f) { let n=0 ; while(this.valueOf() > n) f(n++) }

就像在ruby中:

> (3).times(console.log)
0
1
2

其他回答

对我来说,这是许多级别的开发人员最容易理解的答案 Const times = (n, callback) => { 而(n) { 回调(); n——; } } Times (10, ()=> console.log('hello'))

答案:2015年12月9日

就我个人而言,我发现公认的答案既简洁(好)又简洁(坏)。欣赏这个说法可能是主观的,所以请阅读这个答案,看看你是否同意

问题中给出的例子类似Ruby的例子:

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

在JS中使用下面的方法来表达这一点将允许:

times(x)(doStuff(i));

代码如下:

let times = (n) => {
  return (f) => {
    Array(n).fill().map((_, i) => f(i));
  };
};

就是这样!

简单的示例用法:

let cheer = () => console.log('Hip hip hooray!');

times(3)(cheer);

//Hip hip hooray!
//Hip hip hooray!
//Hip hip hooray!

或者,下面是被接受的答案的例子:

let doStuff = (i) => console.log(i, ' hi'),
  once = times(1),
  twice = times(2),
  thrice = times(3);

once(doStuff);
//0 ' hi'

twice(doStuff);
//0 ' hi'
//1 ' hi'

thrice(doStuff);
//0 ' hi'
//1 ' hi'
//2 ' hi'

边注-定义一个范围函数

一个类似的/相关的问题,使用基本非常相似的代码结构,可能是(核心)JavaScript中是否有一个方便的范围函数,类似于下划线的范围函数。

创建一个包含n个数字的数组,从x开始

下划线

_.range(x, x + n)

ES2015

一些替代方案:

Array(n).fill().map((_, i) => x + i)

Array.from(Array(n), (_, i) => x + i)

演示使用n = 10, x = 1:

> Array(10).fill().map((_, i) => i + 1)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

> Array.from(Array(10), (_, i) => i + 1)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

在我运行的一个快速测试中,使用我们的解决方案和doStuff函数,上述每个方法都运行了一百万次,前一种方法(Array(n).fill())被证明略快一些。

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建议。

我还有另一个选择

[...Array(30).keys()]

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

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

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