Generators with function*0%

Generators with function*

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Generators with function* in Modern JavaScript

While custom iterators are powerful, manually managing state variables and returning { value, done } boilerplate can be tedious. Generators—defined using the function* syntax and the yield operator—provide a clean, stateful way to define iterative algorithms.


1. Syntax & Core Mechanics

A generator function returns a Generator object, which conforms to both the Iterable and Iterator protocols simultaneously:

JavaScript
function* numberSequence() {
console.log('Sequence started');
yield 1;
console.log('Resumed after 1');
yield 2;
console.log('Resumed after 2');
yield 3;
console.log('Sequence finished');
}
 
// Calling the generator does NOT execute code immediately!
// It returns a Generator Iterator:
const gen = numberSequence();
 
console.log(gen.next()); // Prints: 'Sequence started', Returns: { value: 1, done: false }
console.log(gen.next()); // Prints: 'Resumed after 1', Returns: { value: 2, done: false }
console.log(gen.next()); // Prints: 'Resumed after 2', Returns: { value: 3, done: false }
console.log(gen.next()); // Prints: 'Sequence finished', Returns: { value: undefined, done: true }
Output
Generator Execution Pause/Resume:
gen.next() ──► Executes until first 'yield' ──► Pauses execution!
gen.next() ──► Resumes from pause point ──► Pauses at next 'yield'!

2. Infinite Generators & Lazy Evaluation

Because generators pause until next() is explicitly called, they can represent infinite sequences without consuming infinite memory (Lazy Evaluation):

JavaScript
function* idGenerator() {
let id = 1000;
while (true) {
yield `UID_${id++}`;
}
}
 
const ids = idGenerator();
 
console.log(ids.next().value); // 'UID_1000'
console.log(ids.next().value); // 'UID_1001'
console.log(ids.next().value); // 'UID_1002'
// Memory footprint remains constant!

3. Two-Way Communication: Passing Values into next(value)

The yield keyword is not only an output statement—it can also receive inputs passed to gen.next(arg):

JavaScript
function* conversation() {
const name = yield 'What is your name?';
const role = yield `Nice to meet you, ${name}! What is your role?`;
return `Registered ${name} as ${role}.`;
}
 
const chat = conversation();
 
console.log(chat.next().value); // 'What is your name?'
console.log(chat.next('Priya').value); // 'Nice to meet you, Priya! What is your role?'
console.log(chat.next('Architect').value); // 'Registered Priya as Architect.'

4. Delegating Generators with yield*

The yield* operator delegates iteration to another generator or iterable:

JavaScript
function* frontendTech() {
yield 'HTML';
yield 'CSS';
yield 'JavaScript';
}
 
function* backendTech() {
yield 'Node.js';
yield 'Django';
}
 
function* fullStackCurriculum() {
yield* frontendTech(); // Delegates to frontendTech generator
yield* backendTech(); // Delegates to backendTech generator
yield 'Docker';
}
 
console.log([...fullStackCurriculum()]);
// ['HTML', 'CSS', 'JavaScript', 'Node.js', 'Django', 'Docker']

Interactive Quiz

Practice Quiz

Question 1
How do you declare a generator function in JavaScript?
Question 2
What happens when you invoke a generator function (e.g. const g = myGen())?
Question 3
What is the role of the yield keyword inside a generator?
Question 4
What does the yield* operator do?
Question 5
Can an infinite while (true) loop inside a generator crash the browser with an Out of Memory error?
Next Lesson

Using console methods

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext