在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中有更好的机制。
此解决方案的优点
最容易阅读/使用(我觉得)
返回值可以用作和,也可以忽略
普通es6版本,也链接到TypeScript版本的代码
缺点
——突变。只是内在我不在乎,也许其他人也不在乎。
示例和代码
times(5, 3) // 15 (3+3+3+3+3)
times(5, (i) => Math.pow(2,i) ) // 31 (1+2+4+8+16)
times(5, '<br/>') // <br/><br/><br/><br/><br/>
times(3, (i, count) => { // name[0], name[1], name[2]
let n = 'name[' + i + ']'
if (i < count-1)
n += ', '
return n
})
function times(count, callbackOrScalar) {
let type = typeof callbackOrScalar
let sum
if (type === 'number') sum = 0
else if (type === 'string') sum = ''
for (let j = 0; j < count; j++) {
if (type === 'function') {
const callback = callbackOrScalar
const result = callback(j, count)
if (typeof result === 'number' || typeof result === 'string')
sum = sum === undefined ? result : sum + result
}
else if (type === 'number' || type === 'string') {
const scalar = callbackOrScalar
sum = sum === undefined ? scalar : sum + scalar
}
}
return sum
}
TypeScipt版本
https://codepen.io/whitneyland/pen/aVjaaE?editors=0011
在函数式范式中,重复通常是一个无限递归函数。要使用它,我们需要惰性求值或延续传递样式。
惰性求值函数重复
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
我做了这个:
function repeat(func, times) {
for (var i=0; i<times; i++) {
func(i);
}
}
用法:
repeat(function(i) {
console.log("Hello, World! - "+i);
}, 5)
/*
Returns:
Hello, World! - 0
Hello, World! - 1
Hello, World! - 2
Hello, World! - 3
Hello, World! - 4
*/
变量i返回它循环的次数-如果你需要预加载x数量的图像,这很有用。