为什么生成器不支持 map()?
因为它太容易填写为用户态实现。ES3 也不包含数组迭代方法,也许会在 ES7 中看到用于迭代器的转换器 :-)
生成器,其功能非常类似于数组
不,请停止并区分迭代器和生成器:
- 迭代器是具有
.next()
符合迭代器协议的方法的对象。
- 生成器是由生成器函数 (
function*
) 创建的迭代器。它的.next()
方法接受一个参数,该参数是yield
生成器函数内部的每个结果。它也有.return()
和.throw()
方法。
您将主要对迭代器感兴趣,我们不将值传递给next
,并且不关心最终结果 - 就像for of
循环一样。我们可以轻松地使用所需的方法扩展它们:
var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
IteratorPrototype.map = function*(f) {
for (var x of this)
yield f(x);
};
IteratorPrototype.filter = function*(p) {
for (var x of this)
if (p(x))
yield x;
};
IteratorPrototype.scan = function*(f, acc) {
for (var x of this)
yield acc = f(acc, x);
return acc;
};
IteratorPrototype.reduce = function(f, acc) {
for (var x of this)
acc = f(acc, x);
return acc;
};
这些对于开始和最常见的用例应该足够了。适当的库会将其扩展到生成器,以便适当地传递值,并且还将处理迭代器在耗尽之前只能使用一次的问题(与数组相反)。