- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript Iterators
JavaScript Generators & Iterators
JavaScript Iterators
An iterator is an object with a
nextmethod that hands out one value at a time.
Arrays, strings, Maps and Sets all work with for of because they follow this same protocol underneath.
Seeing it directly explains what a loop is really doing.
Example
Example
javascript
const numbers = [1, 2, 3];
const iterator = numbers[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());Each call gives an object with a value and whether it is finished.
The Iterator Protocol
An iterator is any object with a next() method.
Each call returns { value, done }.
done becomes true once there is nothing left.
Syntax
Syntax
javascript
const iterator = { next() { /* ... */ } };
iterator.next(); // { value: ..., done: false }No special syntax is needed; it is just an object shape.
Walking Through an Array Manually
for of does exactly this, one step per turn.
Example
Example
javascript
const colours = ["red", "green"];
const iterator = colours[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());The third call has nothing left, so done is true.
Writing Your Own Iterator
Any object with a matching next method qualifies.
Example
Example
javascript
function countTo(max) {
let current = 0;
return {
next() {
current++;
return current <= max
? { value: current, done: false }
: { value: undefined, done: true };
}
};
}
const counter = countTo(3);
console.log(counter.next());
console.log(counter.next());This behaves exactly like a built-in iterator.
Draining an Iterator by Hand
A loop that keeps calling next until done is what for of hides.
Example
Example
javascript
function countTo(max) {
let current = 0;
return {
next() {
current++;
return current <= max
? { value: current, done: false }
: { value: undefined, done: true };
}
};
}
const counter = countTo(3);
const values = [];
let result = counter.next();
while (!result.done) {
values.push(result.value);
result = counter.next();
}
console.log(values.join(","));The output is 1,2,3.
Once Done, Always Done
A finished iterator keeps returning done: true.
Example
Example
javascript
const numbers = [1];
const iterator = numbers[Symbol.iterator]();
iterator.next();
console.log(iterator.next().done);
console.log(iterator.next().done);Both later calls agree that it is finished.
Not Every Object Has One
A plain object does not have Symbol.iterator by default.
That is exactly why for of refuses to loop over one.
Example
Example
javascript
const plain = { a: 1, b: 2 };
console.log(typeof plain[Symbol.iterator]);
console.log(typeof [][Symbol.iterator]);The output is undefined then function.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Iterators</title>
</head>
<body>
<h1>Iterators</h1>
<p id="out"></p>
<script>
const colours = ["red", "green", "blue"];
const iterator = colours[Symbol.iterator]();
const seen = [];
let result = iterator.next();
while (!result.done) {
seen.push(result.value);
result = iterator.next();
}
document.getElementById("out").textContent = seen.join(", ");
</script>
</body>
</html>Try It Yourself
Run the above example in the Try It Editor.
Try a string:
Call "hi"[Symbol.iterator]() and step through it the same way.
Important Points
- An iterator is an object with a
next()method. - Each call returns
{ value, done }. for ofis really just repeated calls tonext.- A finished iterator keeps reporting
done: true. - Plain objects do not have
Symbol.iteratorby default.
Conclusion
Every for of loop you have written was using this protocol.
Seeing it directly removes the mystery from generators, next.
It is also the foundation the next lesson builds custom iterables on.
