Um iterável é o mesmo que um iterador ou eles são diferentes?
Parece que, pelas especificações , um iterável é um objeto, por exemplo, obj
que obj[Symbol.iterator]
se refere a uma função, de modo que, quando invocado, retorna um objeto que possui um next
método que pode retornar um {value: ___, done: ___}
objeto:
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)
Portanto, no código acima, bar
é o iterável, wah
o iterador e a next()
interface do iterador.
Então, iterável e iterador são coisas diferentes.
Agora, no entanto, em um exemplo comum de gerador e iterador:
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
No caso acima, gen1
é o gerador e iter1
o iterador, e iter1.next()
fará o trabalho adequado. Mas iter1[Symbol.iterator]
fornece uma função que, quando invocada, devolve iter1
, que é um iterador. Então, iter1
é um iterável e um iterador nesse caso?
Além disso, iter1
é diferente do exemplo 1 acima, porque o iterável no exemplo 1 pode fornecer [1, 3, 5]
quantas vezes quiser [...bar]
, enquanto iter1
é iterável, mas como ele retorna, que é o mesmo iterador todas as vezes, dará apenas [1, 3, 5]
uma vez.
Então, podemos dizer, de forma iterável bar
, quantas vezes podem [...bar]
dar o resultado [1, 3, 5]
- e a resposta é: depende. E é iterável o mesmo que um iterador? E a resposta é: são coisas diferentes, mas podem ser as mesmas quando o iterável se usa como iterador. Isso está correto?
iter1
é um iterável e um iterador neste caso? " - sim. Todos os iteradores nativos também são iteráveis retornando a si mesmos, para que você possa transmiti-los facilmente para construções que esperam ser iteráveis.