1
Because objects are responsible for providing their own iteration mechanism, as we’ll see shortly, it’s actually
possible to create a “bad iterator” that can reverse the value of
done
; that would be considered a faulty iterator.
In general, you should rely on correct iterator behavior.
it
.
next
();
// { value: "Twinkle, twinkle, little bat!", done: false }
it
.
next
();
// { value: "How I wonder what you're at!", done: false }
it
.
next
();
// { value: "Up above the world you fly,", done: false }
it
.
next
();
// { value: "Like a tea tray in the sky.", done: false }
it
.
next
();
// { value: "Twinkle, twinkle, little bat!", done: false }
it
.
next
();
// { value: "How I wonder what you're at!", done: false }
it
.
next
();
// { value: undefined, done: true }
it
.
next
();
// { value: undefined, done: true }
it
.
next
();
// { value: undefined, done: true }
There are a couple of important things to note here. The first is that when
next
gives
us the last page in the book, it tells us we’re not done. This is where the book analogy
breaks down a little bit: when you read the last page of a book, you’re done, right?
Iterators can be used for more than books, and knowing when you’re done is not
always so simple. When you are done, note that
value
is
undefined
, and also note
that you can keep calling
next
, and it’s going to keep telling you the same thing. Once
an iterator is done, it’s done, and it shouldn’t ever go back to providing you data.
While this example doesn’t illustrate it directly, it should be clear to you that we can
do things between the calls to
it.next()
. In other words,
it
will save our place for us.
If we needed to enumerate over this array, we know we can use a
for
loop or a
for...of
loop. The mechanics of the
for
loop are simple: we know the elements in
an array are numeric and sequential, so we can use an index variable to access each
element in the array in turn. But what of the
for...of
loop? How does it accomplish
its magic without an index? As it turns out, it uses an iterator: the
for...of
loop will
work with anything that provides an iterator. We’ll soon see how to take advantage of
that. First, let’s see how we can emulate a
for...of
loop with a
while
loop with our
newfound understanding of iterators:
const
it
=
book
.
values
();
let
current
=
it
.
next
();
while
(
!
current
.
done
) {
console
.
log
(
current
.
value
);
current
=
it
.
next
();
}
Note that iterators are distinct; that is, every time you create a new iterator, you’re
starting at the beginning, and it’s possible to have multiple iterators that are at differ‐
ent places:
const
it1
=
book
.
values
();
const
it2
=
book
.
values
();
// neither iterator have started
176 | Chapter 12: Iterators and Generators