Ответ 1
Почему генераторы не поддерживают map()?
Потому что это слишком просто для заполнения в качестве реализации пользовательской среды. В ES3 также не использовались итерационные методы Array, возможно, в 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;
};
Это должно быть достаточно для начала и наиболее распространенных случаев использования. Правильная библиотека расширит это до генераторов, чтобы значения были переданы соответствующим образом, а также будет решать проблему, что итераторы могут использоваться только один раз, прежде чем они исчерпаны (в отличие от массивов).