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


当前回答

const times = 4;
new Array(times).fill().map(() => console.log('test'));

这段代码将console.log测试4次。

其他回答

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

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

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

下面是另一个不错的选择:

Array.from({ length: 3}).map(...);

最好,就像@Dave Morse在评论中指出的那样,你也可以通过使用Array.from函数的第二个参数来摆脱map调用,就像这样:

Array.from({ length: 3 }, () => (...))

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

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

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

就像在ruby中:

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

在函数式范式中,重复通常是一个无限递归函数。要使用它,我们需要惰性求值或延续传递样式。

惰性求值函数重复

const重复= f = > x = > [x,() = >重复(f) (f (x))); Const take = n => ([x, f]) => n === 0 ?X:取(n - 1) (f()); console.log ( 取(8)(repeat(x => x * 2) (1)) // 256 );

我使用一个thunk(一个没有参数的函数)来实现Javascript中的惰性求值。

延续传递样式的函数重复

const重复= f = > x = > [x, k = > k(重复(f) (f (x)))); Const take = n => ([x, k]) => n == 0 ?X: k(取(n - 1)); console.log ( 取(8)(repeat(x => x * 2) (1)) // 256 );

CPS一开始有点吓人。然而,它总是遵循相同的模式:最后一个参数是continuation(一个函数),它调用自己的主体:k => k(…)。请注意CPS将应用程序翻过来,即take(8)(重复…)变成k(take(8))(…)其中k是部分应用的重复。

结论

通过将重复(repeat)与终止条件(take)分离,我们获得了灵活性——将关注点分离到痛苦的尽头:D