Suggest an editImprove this articleRefine the answer for “The function* keyword”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`function*` declares a generator function: when you call it, it does not run straight away, it returns a generator object (an iterator).** You drive execution through that object by hand with `.next()`, `.throw()` and `.return()`, while inside the body `yield` pauses the function and hands an intermediate value back out. ```javascript function* gen() { yield 1; yield 2; } const iterator = gen(); // the body has not run yet console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: undefined, done: true } ``` **Key point:** the asterisk turns a function into a generator, that is, into code you can run step by step, stop at a `yield` and resume from exactly the same place.Shown above the full answer for quick recall.Answer (EN)Image**The `function*` keyword creates a generator function, which does not run when you call it but instead returns a generator object (an iterator).** That object lets you drive execution of the function by hand, through calls to `.next()`, `.throw()` and `.return()`. ## Theory ### TL;DR - `function*` declares a generator; the asterisk goes right after the word `function`. - Calling a generator returns an iterator, not the result of a computation. - `yield` inside the body hands a value out and pauses execution until the next `.next()`. - The generator object implements the iterator protocol, so it works in `for...of`. - `next(value)` passes a value back inside the function, into the result of the `yield` expression. - `async function*` returns an async iterator, which you walk with `for await...of`. ### Quick example ```javascript function* gen() { yield 1; yield 2; yield 3; } const iterator = gen(); // the function does not run immediately 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 } ``` - The first `gen()` call returns an iterator, not a result. - Every `.next()` runs execution up to the next `yield`. - After the last `yield` the function finishes and reports `done: true`. ### Syntax ```javascript function* functionName(params) { yield value1; yield value2; // ... } ``` - The asterisk (`*`) after the word `function` makes the function a generator. - The `yield` keyword is used inside to pause execution and return an intermediate value. `function* name()`, `function *name()` and `function * name()` are all equivalent, but the settled style is to keep the asterisk next to the word `function`. ### How yield works `yield` is a pause inside a generator function. It does three things: 1. **returns a value** to the outside (the `value` field); 2. **pauses execution** of the function; 3. waits for the next `.next()` call to continue. ```javascript function* greet() { console.log('Start'); yield 'Hello'; console.log('Continuing'); yield 'How are you?'; } const it = greet(); console.log(it.next().value); // "Hello" console.log(it.next().value); // "How are you?" console.log(it.next()); // done: true ``` Between two `yield` statements execution really does stop, which is impossible to achieve with a regular function. ### A generator is an iterator The object returned by `function*` implements the iterator protocol, so you can pass it into `for...of`: ```javascript function* gen() { yield 1; yield 2; } for (const n of gen()) { console.log(n); } ``` Output: ```javascript 1 2 ``` Besides `.next()`, a generator object has two more methods: `.return(value)` finishes the generator early and yields `{ value, done: true }`, while `.throw(error)` raises an error at the point of the current `yield`, so it can be caught inside the generator body with an ordinary `try/catch`. ### How function* differs from a regular function | Feature | `function` | `function*` | | --- | --- | --- | | Returns | a result (`value`) | an iterator (generator object) | | Can pause execution | No | Yes, through `yield` | | Runs immediately | Yes | No, only on `.next()` | | Used for | ordinary operations | lazy evaluation, iterators, streams | | Can take values back in | No | Yes, through `next(value)` | ### Passing values back in, and the async variant The argument of `next(value)` lands inside the generator as the result of the `yield` expression where execution was paused. ```javascript function* conversation() { const name = yield 'What is your name?'; yield `Hello, ${name}!`; } const chat = conversation(); console.log(chat.next().value); // "What is your name?" console.log(chat.next('Maria').value); // "Hello, Maria!" ``` The first `next()` starts the generator, the second passes `'Maria'` back in, and that value lands in `const name`. If you add `async`, you can use `await` inside the generator (ES2018): ```javascript async function* fetchChunks() { yield await Promise.resolve('Chunk 1'); yield await Promise.resolve('Chunk 2'); } for await (const chunk of fetchChunks()) { console.log(chunk); } ``` Async generators return an async iterator and are walked with `for await...of`. Summary: | Property | Description | | --- | --- | | `function*` | Declares a generator function | | What it returns | An iterator (an object with `.next()`, `.throw()`, `.return()`) | | Keyword used inside | `yield` | | Distinctive trait | Code can be executed step by step and paused | | Asynchronous variant | `async function*` | | Main use | Iterators, lazy evaluation, data streams, complex asynchronous processes | ### Common mistakes - **Expecting `gen()` to return a value.** The call returns a generator object; to get a value you need `.next().value`. - **Forgetting the asterisk.** Without `*` the word `yield` in the body becomes a syntax error (in strict mode) or just an ordinary identifier. - **Assuming the code before the first `yield` runs at call time.** It only runs on the first `.next()`. - **Trying to use an arrow function.** Arrow functions cannot be generators, there is no `() => {}` form with an asterisk; for object and class methods there is the shorthand `*name() {}`. - **Ignoring `.return()` and `.throw()`.** These are the standard ways to finish a generator early or to inject an error into it, not exotica. - **Iterating an `async function*` with a plain `for...of`.** You need `for await...of`, otherwise you get promises back.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.