Iterators in JavaScript
Introduction
An iterator is an object with a next() method that returns { value, done }. Built-in types—arrays, strings, Map, Set—provide iterators so for...of works. Custom iterators let you expose lazy sequences and hide internal structure.
Prerequisites
Iterable and Iterator Protocol
- Iterable — has
Symbol.iteratormethod returning an iterator - Iterator — has
next()returning{ value, done: boolean }
javascript
// Manual iterator on array
const arr = ["a", "b", "c"];
const it = arr[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());for...of Uses Iterators
javascript
// String yields characters
for (const ch of "hi") {
console.log(ch);
}
// Map yields [key, value] pairs
const map = new Map([["x", 1], ["y", 2]]);
for (const [key, value] of map) {
console.log(key, value);
}Custom Iterable Object
javascript
// Range iterable 1..n
const range = {
from: 1,
to: 3,
[Symbol.iterator]() {
let current = this.from;
const last = this.to;
return {
next() {
if (current <= last) {
return { value: current++, done: false };
}
return { done: true };
},
};
},
};
for (const n of range) {
console.log(n);
}Iterator Helpers (Modern)
Some environments support Iterator.from, .map, .filter on iterators—check target runtime. Arrays still favor .map for simplicity.
Spread and Destructuring Use Iterators
javascript
// Spread consumes iterable
const set = new Set([1, 2, 3]);
const arr = [...set];
console.log(arr);Mini Example: Linked List Walk
javascript
function createNode(value, next = null) {
return { value, next };
}
const list = {
head: createNode(1, createNode(2, createNode(3))),
[Symbol.iterator]() {
let node = this.head;
return {
next() {
if (!node) return { done: true };
const value = node.value;
node = node.next;
return { value, done: false };
},
};
},
};
for (const v of list) {
console.log(v);
}FAQ
for...in vs for...of?
for...in enumerates keys on objects; for...of iterates values of iterables.
Can I iterate plain objects with for...of?
Not by default—use Object.keys or make the object iterable.
Iterator exhaustion?
After done: true, further next() calls keep returning { done: true }.