ES6(ECMAScript 6)中是否有一种不使用可变变量来循环x次的机制?

256

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

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

但是我不想使用 ++ 操作符或任何可变变量。那么在 ES6 中,有没有其他的方法可以循环 x 次?我喜欢 Ruby 的机制:

但是我不想使用 ++ 操作符或任何可变变量。那么在 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中有一个更好的机制。

4
可变的循环控制变量为什么是个问题?只是一个原则吗? - doldt
3
@doldt - 我正在试图教授JavaScript,但我正试验将可变变量的概念延迟到更晚的阶段。 - at.
6
我们离题有些远了,但是在学习可变变量之前,您确定转向ES6生成器(或任何其他新的、高级的概念)是一个好主意吗? :) - doldt
7
@doldt - 或许吧,我正在尝试。采用函数式编程的方法处理 JavaScript。 - at.
1
使用let关键字在循环中声明变量,其作用域仅限于循环内部。 - ncmathsadist
24个回答

0
我做了这个:
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数量的图像,则非常有用。


0

关注功能方面:

function times(n, f) {
    var _f = function (f) {
        var i;
        for (i = 0; i < n; i++) {
            f(i);
        }
    };
    return typeof f === 'function' && _f(f) || _f;
}
times(6)(function (v) {
    console.log('in parts: ' + v);
});
times(6, function (v) {
    console.log('complete: ' + v);
});

5
"addressing the functional aspect"指的是解决函数方面的问题,然后使用具有可变i的命令式循环。那么使用times而不是普通的for循环的原因是什么? - zerkms
重复使用例如 var twice = times(2); - Nina Scholz
那为什么不直接使用两个 for 循环呢? - zerkms
我不害怕使用for循环。问题是不使用变量,但结果总是某种缓存,也就是变量。 - Nina Scholz
1
“是有些不应该使用变量的” --- 但你仍然在使用它 - i++。将不可接受的东西包装在函数中并不明显会使其更好。 - zerkms

0
我用一个辅助函数包装了@Tieme的答案。
在TypeScript中:
export const mapN = <T = any[]>(count: number, fn: (...args: any[]) => T): T[] => [...Array(count)].map((_, i) => fn())

现在你可以运行:

const arr: string[] = mapN(3, () => 'something')
// returns ['something', 'something', 'something']

-1

生成器?递归?为什么这么讨厌变异?;-)

如果只要我们"隐藏"它是可以接受的,那么就接受使用一元运算符,这样我们就可以保持简单:

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

就像在Ruby中一样:

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

1
赞成简洁易懂,反对过度使用monkeypatch的ruby风格。对那些糟糕的猴子说不。 - mrm
1
@mrm 这是“猴子补丁”吗?难道这不只是扩展的一种情况吗?拥抱并扩展 :) - conny
在 Number(或 String 或 Array 或任何其他你没有编写的类)中添加函数,根据定义,要么是 polyfill,要么是 monkey patch——即使 polyfill 也不被推荐。请阅读“monkey patch”、“polyfill”和推荐的替代方案“ponyfill”的定义。这才是你想要的。 - mrm
要扩展Number,您可以这样做:class SuperNumber extends Number { times(fn) { for (let i = 0; i < this; i ++) { fn(i); } } } - Alexander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接