Photo by Yosuke Ota on Unsplash

On this page

An iterator is any object with a next() method that returns { value, done }. An iterable is anything that can produce such an iterator—usually via [Symbol.iterator](). Built-in loops and spread syntax depend on that contract.

What is an iterator?

From Latin iterare (“to repeat”), an iterator lets you visit each item in a sequence without loading the whole collection into memory at once.

Common ways to walk data in JavaScript:

  • for loops over indices or keys
  • Array methods such as map and filter (they still materialize or scan collections)
  • Iterators and for..of, which consume values lazily through a shared protocol

Why iterators?

You already know loops and array methods. Iterators still matter because:

  • for..of and for await..of call into the iterator protocol under the hood.
  • An iterator can pause between values; the consumer decides when to call next() again.
  • Sequences can be unbounded or expensive to copy into an array; iterators produce values on demand.

Iterator protocol

Technically, an iterator is any object whose next() method returns a result object with:

  • value — the current item (often undefined when done is true)
  • done — true when the sequence is finished

Calling next() is often called consuming the iterator; many iterators are single-pass (you cannot rewind without creating a new iterator).

What is an iterable?

An iterable is a value you can iterate over with for..of or spread. It must provide a [Symbol.iterator]() method that returns a fresh iterator.

Built-in iterables include Array, String, Map, Set, TypedArray, and arguments (in non-arrow functions).

Create a custom iterable

const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
},
};
for (const value of myIterable) {
console.log(value);
}
// 1, 2, 3
console.log([...myIterable]); // [1, 2, 3]

for..of walks values on iterables. for..in walks enumerable string keys on objects—a different loop for a different job.

Iterating over an array

With for..of:

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

Or via the array’s iterator:

const arr = [1, 2, 3, 4];
const it = arr[Symbol.iterator]();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: 4, done: false }
console.log(it.next()); // { value: undefined, done: true }

Iterating over a Map

With for..of (default entries are [key, value] pairs):

const map = new Map([
["key1", "value 1"],
["key2", "value 2"],
]);
for (const [key, value] of map) {
console.log(`${key} and ${value}`);
}

Using the map iterator directly:

const mapIterator = map[Symbol.iterator]();
console.log(mapIterator.next()); // { value: ["key1", "value 1"], done: false }
console.log(mapIterator.next()); // { value: ["key2", "value 2"], done: false }
console.log(mapIterator.next()); // { value: undefined, done: true }

Iterating over a Set

const set = new Set(["Apples", "Bananas"]);
for (const value of set) {
console.log(value);
}
const setIterator = set[Symbol.iterator]();
console.log(setIterator.next()); // { value: "Apples", done: false }
console.log(setIterator.next()); // { value: "Bananas", done: false }
console.log(setIterator.next()); // { value: undefined, done: true }

Create a custom iterator

Manual next()

You can implement next() by hand. It works, but callers cannot tell from the type alone that your object is an iterator—prefer exposing iterables (with [Symbol.iterator]) or generator functions.

function myIterator(start, finish) {
let index = start;
return {
next() {
if (index < finish) {
return { value: index++, done: false };
}
return { value: undefined, done: true };
},
};
}
const it = myIterator(0, 8);
let res = it.next();
while (!res.done) {
console.log(res.value);
res = it.next();
}
// 0 … 7

Relation to generators

Hand-rolled iterators must track state yourself. Generator functions (function*) are the usual way to build iterators: they return an iterator object and use yield for each step. That is the focus of the next chapter.

Continue with Generators in JavaScript.

Search articles

Type a word to search published articles.

Open the search page