Skip to content

Intermediate · Map, Set, iterators, generators and regular expressions · topic 32 of 61 · 25 min

Iterators and the iteration protocol

Explanation

for…of, spread and array destructuring all work through one rule called the iteration protocol. An iterable is an object with a Symbol.iterator method; that method returns an iterator, an object whose next() gives { value, done } each time. Arrays, strings, Maps and Sets are iterable, and you can make your own objects iterable too.

Why learn the protocol?

You have used for…of on arrays, strings, Maps and Sets. How does one loop work on such different things? Each of them follows the same small agreement, the iteration protocol. Once you know it, you can make your own objects work with for…of, spread and destructuring, and you understand generators (next topic) and many library APIs.

Iterator: an object with next()

An iterator is an object with a next() method. Each call returns an object with two properties: value (the next item) and done (true when there are no more items).

javascript
const it = ['tea', 'coffee'][Symbol.iterator]();
console.log(it.next()); // { value: 'tea', done: false }
console.log(it.next()); // { value: 'coffee', done: false }
console.log(it.next()); // { value: undefined, done: true }

Iterable: an object that can give an iterator

An iterable is any object with a method stored under the special key Symbol.iterator. That method returns a fresh iterator. Symbol.iterator is a built-in symbol: a unique key that cannot clash with normal string keys.

for (const x of thing) does this: call thing[Symbol.iterator]() to get an iterator, then call next() again and again, giving you each value, until done is true.

Making your own iterable

javascript
const range = {
  from: 1,
  to: 5,
  [Symbol.iterator]() {
    let current = this.from;
    const last = this.to;
    return {
      next() {
        return current <= last
          ? { value: current++, done: false }
          : { value: undefined, done: true };
      },
    };
  },
};
console.log([...range]);          // [1, 2, 3, 4, 5]
for (const n of range) console.log(n);
const [first, second] = range;    // 1, 2

Who uses the protocol?

  • for…of loops
  • Spread in arrays and calls: [...x], Math.max(...x)
  • Array destructuring: const [a, b] = x
  • Array.from(x), new Map(x), new Set(x), Promise.all(x)

Iterables are lazy

An iterator produces values one at a time, only when asked. That means it can represent a sequence that is huge or even endless, as long as the consumer stops asking. A plain array, in contrast, must hold every element in memory at once.

Careful: Plain objects are NOT iterable: for (const x of { a: 1 }) throws TypeError: object is not iterable. Loop over Object.keys(obj), Object.values(obj) or Object.entries(obj) instead, which are arrays.

Iterator helpers

ES2025 added helper methods directly on iterators: map, filter, take, drop, toArray and more, for example map.keys().filter(...).toArray(). They work lazily, item by item. They are in current browsers and Node; check MDN compatibility if you support older ones.

Think of it like this: An iterator is like the token machine at a bank: each press of the button (next) gives you one token, and when the day's tokens are finished, it shows "done". You never get all tokens at once.
Tip: Many iterators can only be used once. After a for…of finishes, calling next() on the same iterator keeps returning done: true. Get a new one by calling [Symbol.iterator]() (or keys(), values()) again.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Iterators and the iteration protocol · 1/6

Iterators

In this lesson you will learn the rule behind for of loops, called the iteration protocol.

Prefer a video by a teacher? Find free videos on “javascript iterators iterables Symbol.iterator explained” on YouTube ↗

In real life: Paging through API results

An HR system returns employees 100 at a time. A developer wraps the paging logic in an iterable, so the rest of the code just writes for (const emp of allEmployees) without caring about pages. Here the pages are simulated with arrays.

javascript
const pages = [['Asha', 'Ravi'], ['Meena'], ['Kabir', 'Om']];
const allEmployees = {
  [Symbol.iterator]() {
    let page = 0, index = 0;
    return {
      next() {
        while (page < pages.length && index >= pages[page].length) { page++; index = 0; }
        if (page >= pages.length) return { value: undefined, done: true };
        return { value: pages[page][index++], done: false };
      },
    };
  },
};
console.log([...allEmployees]); // ['Asha', 'Ravi', 'Meena', 'Kabir', 'Om']

Practice (0/2 done)

Task 1 · Code · Javascript

Write firstTwo(iterable) that returns an array of the first two values of ANY iterable by calling its iterator's next() twice (do not convert the whole thing to an array).

Task 2 · Code · Javascript

Write range(from, to, step = 1) that returns an ITERABLE object (not an array) producing from, from + step, … up to and including to.

Quick quiz

Question 1

1.What does an iterator's next() return?

Question 2

2.What makes an object iterable?

Question 3

3.for (const x of { a: 1 }) {} does what?

Question 4

4.Which of these does NOT use the iteration protocol?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does an iterator's next() return?

Answer: An object { value, done }

next() returns { value, done }.

What makes an object iterable?

Answer: A [Symbol.iterator] method

The Symbol.iterator method returns an iterator.

for (const x of { a: 1 }) {} does what?

Answer: Throws TypeError: not iterable

Plain objects do not have Symbol.iterator.

Which of these does NOT use the iteration protocol?

Answer: for…in

for…in walks enumerable property keys, not iterators.

What does next() do when an iterator has no items left?Related

Answer: Raises StopIteration

StopIteration is the signal that the iterator is finished. A for loop catches it for you.

From Iterators and generators

for (const k in ["a", "b"]) console.log(k); What is printed?Related

Answer: 0, 1 (as strings)

for…in gives keys, and array keys are the indexes as strings.

From Loops: for, while, do…while, for…of and for…in

What does calling a generator function return?Related

Answer: A generator object

The body does not run until next() is called.

From Generators

What does it->first give for a std::map iterator?Related

Answer: The key

Map elements are pairs: first is the key, second is the value.

From Iterators: the glue between containers and algorithms

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Map, Set, iterators, generators and regular expressions” before its exam: Generators, Regular expressions: the basics, Regular expressions in practice.
  2. Module 7 exam: Collections, iterators and regular expressions · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Asynchronous JavaScript. 61 topics left in the course before the final exam.

← Previous: Map and Set