Czy iterowalność jest taka sama jak iterator, czy też są różne?
Wydaje się, że ze specyfikacji iterowalny jest obiekt, powiedzmy, obj
taki, który obj[Symbol.iterator]
odnosi się do funkcji, więc po wywołaniu zwraca obiekt, który ma next
metodę, 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 bar
jest iterowalny i wah
jest 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 gen1
jest to generator i iter1
iterator, 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 iter1
w tym przypadku jest zarówno iterowalny, jak i iterator?
Poza tym iter1
różni się od powyższego przykładu 1, ponieważ iterowalność w przykładzie 1 może dawać [1, 3, 5]
tyle razy [...bar]
, ile iter1
potrzeba , 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?
iter1
w 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.