Mastering JavaScript Iterators and Generators: A Complete Guide
JavaScript is packed with features that make working with data structures powerful and efficient. Among them, Iterators and Generators stand out as advanced concepts that give developers more control over looping and lazy evaluation.
In this article, we’ll dive deep into what iterators and generators are, why they matter, and how to use them effectively in your code.
What is an Iterator?
An iterator is an object that defines a sequence and allows you to access elements one at a time.
In JavaScript, iterators follow a standard protocol called the Iterator Protocol.
Iterator Protocol
An object is considered an iterator if it has a method called next().
The next() method should return an object with two properties:
· value → The next value in the sequence.
· done → A boolean indicating whether the sequence has ended.
Example: Custom Iterator
function createIterator(array) {let index = 0;return {next: function() {if (index < array.length) {return { value: array[index++], done: false };} else {return { value: undefined, done: true };}}};}const myIterator = createIterator([1, 2, 3]);console.log(myIterator.next()); // { value: 1, done: false }console.log(myIterator.next()); // { value: 2, done: false }console.log(myIterator.next()); // { value: 3, done: false }console.log(myIterator.next()); // { value: undefined, done: true }Iterables in JavaScript
Closely related to iterators are iterables.
An object is iterable if it follows the Iterable Protocol.
The iterable protocol requires that an object must have a method named [Symbol.iterator]() which returns an iterator.
Example: Iterable Object
const myIterable = {items: [10, 20, 30],[Symbol.iterator]() {let index = 0;return {next: () => {if (index < this.items.length) {return { value: this.items[index++], done: false };} else {return { value: undefined, done: true };}}};}};or (const val of myIterable) {console.log(val); // 10, 20, 30}Built-in Iterables
JavaScript provides built-in iterables:
· Arrays
· Strings
· Maps
· Sets
Get Imantha Gihan’s stories in your inbox
Join Medium for free to get updates from this writer.
· NodeLists (from the DOM)
These can be used directly with for...of loops, spread syntax (...), and destructuring.
Example:
const str = "Hello";for (const char of str) {console.log(char);}What is a Generator?
A generator is a special kind of function in JavaScript that makes writing iterators easier.
Generators are defined using the function* syntax.
Key Features of Generators
· They return iterator objects.
· Use the yield keyword to produce values one at a time.
· Execution can be paused and resumed.
Example: Simple Generator
function* simpleGenerator() {yield 1;yield 2;yield 3;}const gen = simpleGenerator();console.log(gen.next()); // { value: 1, done: false }console.log(gen.next()); // { value: 2, done: false }console.log(gen.next()); // { value: 3, done: false }console.log(gen.next()); // { value: undefined, done: true }Passing Values into Generators
Generators are not one-way streets. You can send values back into them using next(value).
function* greetGenerator() {const name = yield "What is your name?";yield `Hello, ${name}!`;}const gen = greetGenerator();onsole.log(gen.next().value); // "What is your name?"console.log(gen.next("Imaa").value); // "Hello, Imaa!"Infinite Generators
Unlike arrays, generators can produce infinite sequences because they yield values lazily.
function* infiniteCounter() {let i = 0;while (true) {yield i++;}}const counter = infiniteCounter();console.log(counter.next().value); // 0console.log(counter.next().value); // 1console.log(counter.next().value); // 2Combining Iterators and Generators
Generators simplify the creation of iterators since they automatically implement the iterator protocol.
This makes them very powerful for handling streams of data, asynchronous tasks, or complex iteration logic.
Real-World Use Cases
1. Lazy evaluation — Generate values only when needed.
2. Working with infinite sequences — Like IDs, timestamps, counters.
3. Data streaming — Process large datasets without loading everything into memory.
4. Asynchronous operations — Generators can pause execution, useful in frameworks like Redux-Saga.
Conclusion
Iterators and generators are advanced yet essential features in JavaScript.
· Iterators give you fine-grained control over sequences.
· Generators make writing iterators easier with yield and lazy evaluation.
By mastering these concepts, you’ll unlock more powerful ways to handle data, create cleaner loops, and design scalable applications.






