Iterators in JavaScript
An iterator is an object that provides a sequence of values, one at a time, through a next()
method.
- The
next()
method returns an object:
{ value: any, done: boolean }
value
: The current value in the sequence.done
:true
if the iteration is complete, otherwisefalse
.- Iterator Protocol: Any object with a
next()
method that returns{value, done}
is an iterator.
Basic Example
const array = [1, 2, 3];
const iterator = array[Symbol.iterator](); // Built-in iterator
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
Characteristics of Iterators
- Sequential Access: Provides values one at a time.
- Single-use: Once consumed, you need a new iterator for a new iteration.
- Built-in Support: Arrays, strings, Set, Map, and generator objects.
Creating Custom Iterators
You can manually define an iterator by creating an object with a next()
method:
const myIterable = {
items: [10, 20, 30],
[Symbol.iterator]() {
let index = 0;
return {
next: () => index < this.items.length
? { value: this.items[index++], done: false }
: { done: true }
};
}
};
const iterator = myIterable[Symbol.iterator]();
console.log(iterator.next()); // { value: 10, done: false }
console.log(iterator.next()); // { value: 20, done: false }
console.log(iterator.next()); // { value: 30, done: false }
console.log(iterator.next()); // { done: true }
Iterators with Set and Map
Set Iterators
.values()
: Iterator for values.keys()
: Same as.values()
(for Map compatibility).entries()
: Iterator for[value, value]
pairs
const set = new Set([1, 2, 3]);
const values = set.values();
console.log(values.next()); // { value: 1, done: false }
Map Iterators
.entries()
:[key, value]
iterator.keys()
: Iterator for keys.values()
: Iterator for values
const map = new Map([["apples", 500], ["bananas", 300]]);
const entries = map.entries();
console.log(entries.next()); // { value: ["apples", 500], done: false }
Iterators and References
Iterators yield references to objects in collections. Modifying them affects the original:
const map = new Map([[{ id: 1 }, 500]]);
const key = map.keys().next().value;
key.id = 2;
console.log([...map][0][0].id); // 2
Use Cases
- Custom Iteration: Define specific iteration behavior for objects/classes.
- Lazy Evaluation: Combine with generators for on-demand value production.
- Data Processing: Iterate Sets or Maps for filtering, mapping, or transforming values.
- Integration with
for...of
: Use iterators under the hood for looping.
Limitations
- Single-use: Cannot rewind; create a new iterator to iterate again.
- Non-Iterable Types: WeakSet and WeakMap do not provide iterators.
- Manual Management: Custom iterators need careful state tracking.