What is an iterator?
What an iterator is
An iterator is an object that steps through (iterates) the elements of another data structure: an array, string, Set, Map, and so on.
It implements a special interface: it has a next() method,
which returns an object shaped like:
{ value: <value>, done: <boolean flag> }Example of a simple iterator
const iterator = {
current: 1,
last: 3,
next() {
if (this.current <= this.last) {
return { value: this.current++, done: false };
} else {
return { done: true };
}
}
};
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()); // { done: true }An iterator keeps its own state and knows where it "stopped".
What makes an iterator special
Iterators are a universal way to iterate.
For example, arrays, strings, Map, and Set are already iterable out of the box;
they have a special symbolic key, Symbol.iterator.
Example: an array's built-in iterator
const arr = [10, 20, 30];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // { value: 10, done: false }
console.log(iterator.next()); // { value: 20, done: false }
console.log(iterator.next()); // { value: 30, done: false }
console.log(iterator.next()); // { value: undefined, done: true }That is, for...of does exactly the same thing under the hood.
for...of and iterators
const arr = [1, 2, 3];
for (const value of arr) {
console.log(value);
}
// 1
// 2
// 3The for...of loop automatically calls arr[Symbol.iterator]()
and iterates the values until done: true.
Creating your own iterable object
To make your own object "iterable",
you need to define a method with the key Symbol.iterator.
const range = {
from: 1,
to: 5,
[Symbol.iterator]() {
let current = this.from;
const last = this.to;
return {
next() {
if (current <= last) {
return { value: current++, done: false };
} else {
return { done: true };
}
}
};
}
};
for (const num of range) {
console.log(num); // 1 2 3 4 5
}Now range can be used with for...of, Array.from(), ...spread, and other constructs.
Using iterators in other contexts
| Construct | What it does |
|---|---|
for...of | Iterates over iterable values |
...spread | Expands an iterator |
Array.from(iterable) | Converts an iterator into an array |
Destructuring [a, b] = iterable | Extracts values via an iterator |
Example:
const set = new Set(['a', 'b', 'c']);
const arr = [...set]; // ['a', 'b', 'c']This works because Set has a built-in Symbol.iterator.
Async iterators
Introduced in ES2018:
async iterators return promises from next().
const asyncIterable = {
async *[Symbol.asyncIterator]() {
yield 'A';
yield 'B';
yield 'C';
}
};
for await (const value of asyncIterable) {
console.log(value);
}
// A
// B
// CThis is used for asynchronous data streams (for example, reading files, API streams).
Iterator vs Iterable
| Concept | What it is | Example |
|---|---|---|
| Iterable | An object that has a [Symbol.iterator]() method | an array, a string, a Set |
| Iterator | An object that has a next() method | the result of calling arr[Symbol.iterator]() |
Example:
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator](); // an iteratorA short summary
| Term | Description |
|---|---|
| Iterator | An object with a next() method that returns { value, done } |
| Iterable | An object that implements the [Symbol.iterator]() method |
| done | A flag marking the end of the sequence (true means iteration is finished) |
| value | The current value |
| Used in | for...of, spread, Array.from(), destructuring |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.