Compile Ready
Module 11 · Advanced JavaScript

Iterators

Advanced13m read20m practice33m total
IteratorsIterable ProtocolSymbol.iteratorfor...of

Introduction

The iterator protocol is JavaScript's standard way to pull values one at a time from a sequence. An iterator has a next() method that returns { value, done }. An iterable has a Symbol.iterator method that returns an iterator.

This protocol explains why arrays, strings, maps, sets, generators, spread, destructuring, and for...of all work together.

Why This Matters

Iterator questions test protocol-level JavaScript, not memorized APIs. They also prepare you to design custom collections that integrate with language syntax and to reason about lazy iteration performance.

Theory

Iterator protocol

An iterator is any object with a next() method. Each call returns an object with value and done. When done is true, iteration is complete.

Iterable protocol

An iterable is any object with a method at Symbol.iterator. That method returns an iterator. for...of, spread, array destructuring, Array.from, Map, and Set consume iterables.

Iterator vs iterable

An iterator produces values. An iterable can produce an iterator. Many objects are both: a generator object is iterable because its Symbol.iterator returns itself.

Fresh iterators matter

For reusable collections, Symbol.iterator should return a fresh iterator each time. Otherwise one loop can accidentally exhaust the collection for future consumers.

Visual Diagrams

Iterable and iterator relationship
iterable object
   | has Symbol.iterator()
   v
iterator object
   | next()
   v
{ value, done }

Language features call `Symbol.iterator` and then repeatedly call `next()`.

Code Examples

Make a plain object iterable

This collection returns a fresh iterator, so it can be iterated more than once.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1var bag = {
2 values: ['x', 'y'],
3 [Symbol.iterator]: function () {
4 var index = 0;
5 var values = this.values;
6 return {
7 next: function () {
8 if (index < values.length) {
9 return { value: values[index++], done: false };
10 }
11 return { value: undefined, done: true };
12 }
13 };
14 }
15};
16
17for (var value of bag) {
18 console.log(value);
19}
20console.log([...bag].join('-'));

Coding Exercises

Create an iterable numeric range object

Medium

Implement createRange(start, end, step) that returns an iterable object. It should work with for...of, spread, positive steps, and negative steps. Throw if step is zero.

Interview Questions

1What is the difference between an iterator and an iterable?

An iterator has next() and produces { value, done }. An iterable has [Symbol.iterator]() and returns an iterator. for...of requires an iterable, not merely an object with next().

Asked at:GoogleMicrosoftShopify

Follow-ups

  • Why should reusable collections return fresh iterators?
  • Are generator objects iterable?
2Which language features consume iterables?

for...of, spread syntax, array destructuring, Array.from, Promise.all, Map, Set, and many library APIs consume iterables through Symbol.iterator.

Quiz

1. What method must a custom object define to be consumed by `for...of`?

Summary

  • An iterator has `next()` and returns `{ value, done }`.
  • An iterable has `[Symbol.iterator]()` returning an iterator.
  • Arrays, strings, maps, sets, and generators are iterable.
  • Reusable custom collections should return a fresh iterator each time.

Cheat Sheet

Iterator: { next() { return { value, done }; } }.

Iterable: object with [Symbol.iterator]() returning an iterator.

Consumers: for...of, spread, destructuring, Array.from, Map, Set.

Best practice: fresh iterator for reusable collections.