Czy iterowalność jest taka sama jak iterator, czy też są różne?
Wydaje się, że ze specyfikacji iterowalny jest obiekt, powiedzmy, objtaki, który obj[Symbol.iterator]odnosi się do funkcji, więc po wywołaniu zwraca obiekt, który ma nextmetodę, która może zwrócić {value: ___, done: ___}obiekt:
function foo() {
let i = 0;
const wah = {
next: function() {
if (i <= 2) return { value: (1 + 2 * i++), done: false }
else return { value: undefined, done: true }
}
};
return wah; // wah is iterator
}
let bar = {} // bar is iterable
bar[Symbol.iterator] = foo;
console.log([...bar]); // [1, 3, 5]
for (a of bar) console.log(a); // 1 3 5 (in three lines)
Tak więc w powyższym kodzie barjest iterowalny i wahjest iteratorem, a także next()interfejsem iteratora.
Tak więc iterowalność i iterator to różne rzeczy.
Teraz jednak we wspólnym przykładzie generatora i iteratora:
function* gen1() {
yield 1;
yield 3;
yield 5;
}
const iter1 = gen1();
console.log([...iter1]); // [1, 3, 5]
for (a of iter1) console.log(a); // nothing
const iter2 = gen1();
for (a of iter2) console.log(a); // 1 3 5 (in three lines)
console.log(iter1[Symbol.iterator]() === iter1); // true
W powyższym przypadku gen1jest to generator i iter1iterator, iter1.next()który wykona właściwą pracę. Ale iter1[Symbol.iterator]daje funkcję, która po wywołaniu zwraca iter1, która jest iteratorem. Czy iter1w tym przypadku jest zarówno iterowalny, jak i iterator?
Poza tym iter1różni się od powyższego przykładu 1, ponieważ iterowalność w przykładzie 1 może dawać [1, 3, 5]tyle razy [...bar], ile iter1potrzeba , podczas gdy jest iterowalna, ale ponieważ zwraca się, która za każdym razem jest tym samym iteratorem, da tylko [1, 3, 5]raz.
Możemy więc powiedzieć, w przypadku iteracji bar, ile razy można [...bar]dać wynik [1, 3, 5]- i odpowiedź brzmi: to zależy. Czy iterowalność jest taka sama jak iterator? Odpowiedź brzmi: są to różne rzeczy, ale mogą być takie same, gdy iterowalny używa siebie jako iteratora. Czy to jest poprawne?
iter1w tym przypadku jest zarówno iterowalny, jak i iterator? ” - tak. Wszystkie natywne iteratory są również iterowalne, zwracając się, dzięki czemu można łatwo przekazać je do konstrukcji oczekujących iteracji.