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:trueif 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.
