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


当前回答

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,控制台

其他回答

答案: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())被证明略快一些。

我来晚了,但由于这个问题经常出现在搜索结果中,我只想添加一个解决方案,我认为它在可读性方面是最好的,同时不长(这对于任何代码库都是理想的)。它会变异,但我愿意为KISS原则做出妥协。

let times = 5
while( times-- )
    console.log(times)
// logs 4, 3, 2, 1, 0

这是我能想到的在range内创建列表/数组的最简单的方法

Array.from(Array(max-min+1), (_, index) => index+min)

我把它放在这里。如果你正在寻找一个不使用数组的紧凑函数,并且你对可变性/不可变性没有问题:

var g =x=>{/*your code goes here*/x-1>0?g(x-1):null};
 

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,控制台