Generator Functions
In short: a generator function, written function* name() { ... },
doesn't run when you call it — calling it just creates a generator
object, paused before its first line. Each call to .next() resumes it
and runs code up to the next yield, then pauses again right there,
with every local variable exactly as it was. That returned { value, done } follows the same shape as any other iterator — because a generator
is an iterator, which means it also works directly in for...of and
the spread operator.

Step through a generator one yield at a time
Calling a generator function produces the generator object immediately,
but none of its body runs until the first .next():
Nothing prints until the first it.next() — that's when "starting"
finally runs, up to yield "Blue Hour", where execution freezes and
{ value: "Blue Hour", done: false } is returned. The second next()
picks up exactly where it left off, runs "resumed once", reaches the
next yield, and pauses again. The third next() runs the last line and
finishes, giving { value: undefined, done: true } — there's no more
yield left to stop at.
Use a generator directly in for...of
A generator's built-in [Symbol.iterator] returns itself, so it plugs
straight into anything that consumes an iterable:
for...of calls .next() on the generator automatically, printing each
yielded title and stopping once done is true — no manual iterator
protocol needed, the same way it works for arrays. [...songTitles()]
collects every yielded value into a real array,
["Blue Hour", "Red Dawn"].
Quick practice
What happens when you call a generator function, like songTitles(), without calling .next()?
What does each call to .next() do on a generator?
After the last yield has been reached and passed, what does the next .next() call return?
Why does for (const title of songTitles()) { ... } work without calling .next() manually?
What prints first when running function* g() { console.log("A"); yield 1; } const it = g(); console.log("B"); it.next();?
🎯 Your turn
Trace
function* songTitles() { console.log("starting"); yield "Blue Hour"; console.log("resumed once"); yield "Red Dawn"; console.log("resumed twice"); } const it = songTitles(); it.next(); it.next(); it.next();
line by line, explaining what prints and when, and why calling
songTitles() alone doesn't print "starting" immediately.
Write your explanation and submit it — there's no code to run here, just your reasoning.
