JavaScript Iterators
In JavaScript, an iterator represents a sequence of values. It is an object that has a next()
function that returns a POJO with two properties:
value
: The next value in the sequence.done
: If truthy, means the sequence is done.
For example, the below object is an iterator representing a sequence of even numbers.
let num = 0;
const iterator = {
next: () => {
num += 2;
return { value: num, done: false };
}
};
Iterators and Iterables
Iterators are typically not useful on their own. Instead, in JavaScript, you normally
work with iterables. An iterable is an object with a Symbol.iterator
function that
returns an iterator. You can think of an iterable's Symbol.iterator
function as a factory
function for iterators.
const iterable = {
[Symbol.iterator]: function factory() {
let num = 0;
const iterator = {
next: () => {
num += 2;
return { value: num, done: false };
}
};
return iterator;
}
};
Iterables work nicely with several JavaScript language constructs and built-in functions.
For example, you can iterate over an iterable using a for/of
loop.
const oneThruTen = {
[Symbol.iterator]: function() {
let num = 0;
return { next: () => ({ value: ++num, done: num > 10 }) }
}
};
for (const num of oneThruTen) {
num; // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
}
Note that you cannot iterate over an iterator using a for/of
loop, only an iterable.
Converting an Iterable to an Array
There are two ways to convert an iterable to an array. First, JavaScript has a built-in
Array.from()
function that can convert an iterable to an array:
const oneThruTen = {
[Symbol.iterator]: function() {
let num = 0;
return { next: () => ({ value: ++num, done: num > 10 }) }
}
};
Array.from(oneThruTen); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
The spread operator also works with iterables. You can use it to convert an iterable to an array as shown below.
const oneThruTen = {
[Symbol.iterator]: function() {
let num = 0;
return { next: () => ({ value: ++num, done: num > 10 }) }
}
};
[...oneThruTen]; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]