What are Iterators?
Iterators are just objects with a specific interface designed for iteration. All iterator objects have a next()
method that returns a result object. The result object has two properties: value
, which is the next value, and done
, which is a boolean that’s true
when there are no more values to return. The iterator keeps an internal pointer to a location within a collection of values and with each call to the next()
method, it returns the next appropriate value.
If you call next()
after the last value has been returned, the method returns done
as true
and value
contains the return value for the iterator. That return value is not part of the data set, but rather a final piece of related data, or undefined
if no such data exists. An iterator’s return value is similar to a function’s return value in that it’s a final way to pass information to the caller.
With that in mind, creating an iterator using ECMAScript 5 is fairly straightforward:
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
};
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: 3, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
// for all further calls
console.log(iterator.next()); // "{ value: undefined, done: true }"
The createIterator()
function returns an object with a next()
method. Each time the method is called, the next value in the items
array is returned as value
. When i
is 3, done
becomes true
and the ternary conditional operator that sets value
evaluates to undefined
. These two results fulfill the special last case for iterators in ECMAScript 6, where next()
is called on an iterator after the last piece of data has been used.
As this example shows, writing iterators that behave according to the rules laid out in ECMAScript 6 is a bit complex.
Fortunately, ECMAScript 6 also provides generators, which make creating iterator objects much simpler.