References

Beginner-friendly references for web development, with live, editable examples.

The JavaScript function* statement

Statement JavaScript All modern browsers Updated
Quick answer

A generator function, written function*, can pause and resume — each time it hits a yield it produces a value and suspends until you ask for the next. Calling it returns an iterator; you pull values with .next() or loop it with for...of. Generators produce sequences lazily, one value at a time.

Overview

A generator function is a special kind of function, marked with an asterisk (function* name()), that can pause itself. Inside it, the yield keyword produces a value and freezes execution right there; the function only continues when the caller asks for the next value. This pause-and-resume ability is unlike a normal function, which runs start to finish in one go.

Calling a generator function doesn't run its body — it returns a generator object, which is an iterator. You advance it with .next(), which runs until the next yield and returns { value, done }. More commonly you just loop it with for...of or spread it ([...gen()]), since generators are iterable.

The big win is laziness: values are produced one at a time, only as requested, so a generator can represent a huge or even infinite sequence (an ID generator, an endless counter) without computing everything up front. They're also the basis for custom iterators — define [Symbol.iterator] as a generator to make any object iterable. In day-to-day app code they're relatively niche (async/await covers what generators were once used for in async flows), but for lazy sequences and custom iteration they're the right tool.

Syntax

function* range(start, end) {
  for (let i = start; i <= end; i++) {
    yield i;   // produce a value and pause
  }
}

const gen = range(1, 3);
gen.next();          // { value: 1, done: false }
[...range(1, 3)];    // [1, 2, 3]
for (const n of range(1, 3)) { /* 1, 2, 3 */ }

Example

Live example
<pre id="out" style="font:15px ui-monospace,monospace"></pre>
<script>
  function* idMaker() {
    let id = 1;
    while (true) yield id++;   // infinite, but lazy
  }

  const ids = idMaker();
  const first = [ids.next().value, ids.next().value, ids.next().value];

  document.getElementById('out').textContent = 'ids: ' + first.join(', '); // 1, 2, 3
</script>

Best practices

  • Use generators for lazy sequences — values produced on demand, including infinite ones.
  • Consume them with for...of or spread ([...gen()]), since they're iterable.
  • Define [Symbol.iterator] as a generator to make a custom object iterable.
  • Remember calling a generator returns an iterator and runs nothing until .next() (or iteration).

Frequently asked questions

What is a generator function in JavaScript?
A function written function* that can pause at each yield and resume later, producing a sequence of values one at a time.
How do I get values from a generator?
Call .next() for one value at a time (returns { value, done }), or loop with for...of / spread it.
What are generators used for?
Lazy and infinite sequences, custom iterators, and producing values on demand without computing them all up front.
What is the difference between function and function*?
A normal function runs to completion; a function* can pause at yield and resume, returning an iterator.