Is an iterable the same as an iterator, or are they different?
It seems, from the specifications, an iterable is an object, say, obj
, such that obj[Symbol.iterator]
refers to a function, so that when invoked, returns an object that has a next
method that can return a {value: ___, done: ___}
object:
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)
So in the code above, bar
is the iterable, and wah
is the iterator, and the next()
is the iterator interface.
So, iterable and iterator are different things.
Now, however, in a common example of generator and iterator:
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
In the case above, gen1
is the generator, and iter1
is the iterator, and iter1.next()
will do the proper job. But iter1[Symbol.iterator]
does give a function that, when invoked, gives back iter1
, which is an iterator. So iter1
is both an iterable and iterator in this case?
Besides, iter1
is different from the example 1 above, because the iterable in example 1 can give [1, 3, 5]
as many times as wanted using [...bar]
, while iter1
is an iterable, but since it returns itself, which is the same iterator every time, will only give [1, 3, 5]
once.
So we can say, for an iterable bar
, how many times can [...bar]
give the result [1, 3, 5]
-- and the answer is, it depends. And is iterable the same as an iterator? And the answer is, they are different things, but they can be the same, when the iterable uses itself as the iterator. Is that correct?
iter1
is both an iterable and iterator in this case?" - yes. All native iterators are also iterable by returning themselves, so that you can easily pass them into constructs that expect an iterable. – Pensioner