Skip to main content

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:

javascript
{ value: <value>, done: <boolean flag> }

Example of a simple iterator

javascript
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

javascript
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

javascript
const arr = [1, 2, 3]; for (const value of arr) { console.log(value); } // 1 // 2 // 3

The 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.

javascript
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

ConstructWhat it does
for...ofIterates over iterable values
...spreadExpands an iterator
Array.from(iterable)Converts an iterator into an array
Destructuring [a, b] = iterableExtracts values via an iterator

Example:

javascript
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().

javascript
const asyncIterable = { async *[Symbol.asyncIterator]() { yield 'A'; yield 'B'; yield 'C'; } }; for await (const value of asyncIterable) { console.log(value); } // A // B // C

This is used for asynchronous data streams (for example, reading files, API streams).


Iterator vs Iterable

ConceptWhat it isExample
IterableAn object that has a [Symbol.iterator]() methodan array, a string, a Set
IteratorAn object that has a next() methodthe result of calling arr[Symbol.iterator]()

Example:

javascript
const arr = [1, 2, 3]; const iterator = arr[Symbol.iterator](); // an iterator

A short summary

TermDescription
IteratorAn object with a next() method that returns { value, done }
IterableAn object that implements the [Symbol.iterator]() method
doneA flag marking the end of the sequence (true means iteration is finished)
valueThe current value
Used infor...of, spread, Array.from(), destructuring

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.