Lets have an iterator and a generator created to working similarly.
What is the reason they behave differently in for of
loop if it contains break or return statement?
The generator is finished while the iterator still goes after the end of the loop.
function *createGenerator() {
for ( let i=0; i<5; i++ ) {
yield i;
}
}
function createIterator() {
const arr = [1, 2, 3, 4, 5];
return arr[ Symbol.iterator ]();
}
function runForOfLoopOn( iterable ) {
for ( const item of iterable ) {
if ( item == 2 ) {
break;
}
}
}
const iterator = createIterator();
const generator = createGenerator();
runForOfLoopOn( iterator );
runForOfLoopOn( generator );
console.log( 'Iterator is done:', iterator.next().done );
console.log( 'Generator is done:', generator.next().done );
What happens when a
for of
loop contains abreak
orreturn
statement?
When the body of the loop completes abruptly (with a throw
or return
statement) or is broken out of, the IteratorClose
operation will be called. This which basically amounts to invoking the iterator's .return()
method with no arguments if the iterator object has such a method.
What is the reason an iterator and a generator behave differently?
That only the generator has such a return()
method. The ArrayIterator
you created does not have such a method as there is nothing it would need to do. The primary purpose of the return()
method is to release resources, e.g. by triggering finally
clauses in a generator function, but array iterators don't use any. It could clear its reference to the iterated array (which would be "closing" the iterator), but this was deemed unnecessary as array iterators are typically garbage-collected right away.