Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

yield*

BaselineWidely available

Theyield* operator can be used within generator (sync or async) functions to delegate to anotheriterable object, such as aGenerator. Inside async generator functions, it can additionally be used to delegate to another async iterable object, such as anAsyncGenerator.

Try it

function* func1() {  yield 42;}function* func2() {  yield* func1();}const iterator = func2();console.log(iterator.next().value);// Expected output: 42

Syntax

js
yield* expression

Parameters

expressionOptional

An iterable object.

Return value

Returns the value returned by that iterator when it's closed (whendone istrue).

Description

Theyield* expression iterates over the operand and yields each value returned by it. It delegates iteration of the current generator to an underlying iterator — which we will refer to as "generator" and "iterator", respectively.yield* first gets the iterator from the operand by calling the latter's[Symbol.iterator]() method. Then, each time thenext() method of the generator is called,yield* calls the iterator'snext() method, passing the argument received by the generator'snext() method (alwaysundefined for the first call), and yielding the same result object as what's returned from the iterator'snext() method. If the iterator result hasdone: true, then theyield* expression stops executing and returns thevalue of that result.

Theyield* operator forwards the current generator'sthrow() andreturn() methods to the underlying iterator as well. If the current generator is prematurely closed through one of these methods, the underlying iterator will be notified. If the generator'sthrow()/return() method is called, thethrow()/return() method of the underlying iterator is called with the same argument. The return value ofthrow()/return() is handled like thenext() method's result, and if the method throws, the exception is propagated from theyield* expression.

If the underlying iterator doesn't have areturn() method, theyield* expression turns into areturn statement, just like callingreturn() on a suspendedyield expression.

If the underlying iterator doesn't have athrow() method, this causesyield* to throw aTypeError – but before throwing the error, the underlying iterator'sreturn() method is called if one exists.

Examples

Delegating to another generator

In following code, values yielded byg1() are returned fromnext() calls just like those which are yielded byg2().

js
function* g1() {  yield 2;  yield 3;  yield 4;}function* g2() {  yield 1;  yield* g1();  yield 5;}const gen = g2();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: 4, done: false}console.log(gen.next()); // {value: 5, done: false}console.log(gen.next()); // {value: undefined, done: true}

Other Iterable objects

Besides generator objects,yield* can alsoyield other kindsof iterables (e.g., arrays, strings, orargumentsobjects).

js
function* g3(...args) {  yield* [1, 2];  yield* "34";  yield* args;}const gen = g3(5, 6);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: "4", done: false}console.log(gen.next()); // {value: 5, done: false}console.log(gen.next()); // {value: 6, done: false}console.log(gen.next()); // {value: undefined, done: true}

The value of yield* expression itself

yield* is an expression, not a statement, so it evaluates to a value.

js
function* g4() {  yield* [1, 2, 3];  return "foo";}function* g5() {  const g4ReturnValue = yield* g4();  console.log(g4ReturnValue); // 'foo'  return g4ReturnValue;}const gen = g5();console.log(gen.next()); // {value: 1, done: false}console.log(gen.next()); // {value: 2, done: false}console.log(gen.next()); // {value: 3, done: false} done is false because g5 generator isn't finished, only g4console.log(gen.next()); // {value: 'foo', done: true}

Use with async generators

js
async function* g1() {  await Promise.resolve(0);  yield "foo";}function* g2() {  yield "bar";}async function* g3() {  // Can use yield* on both async and sync iterators  yield* g1();  yield* g2();}const gen = g3();console.log(await gen.next()); // {value: "foo", done: false}console.log(await gen.next()); // {value: "bar", done: false}console.log(await gen.next()); // {done: true}

Method forwarding

Thenext(),throw(), andreturn() methods of the current generator are all forwarded to the underlying iterator.

js
const iterable = {  [Symbol.iterator]() {    let count = 0;    return {      next(v) {        console.log("next called with", v);        count++;        return { value: count, done: false };      },      return(v) {        console.log("return called with", v);        return { value: "iterable return value", done: true };      },      throw(v) {        console.log("throw called with", v);        return { value: "iterable thrown value", done: true };      },    };  },};function* gf() {  yield* iterable;  return "gf return value";}const gen = gf();console.log(gen.next(10));// next called with undefined; the argument of the first next() call is always ignored// { value: 1, done: false }console.log(gen.next(20));// next called with 20// { value: 2, done: false }console.log(gen.return(30));// return called with 30// { value: 'iterable return value', done: true }console.log(gen.next(40));// { value: undefined, done: true }; gen is already closedconst gen2 = gf();console.log(gen2.next(10));// next called with undefined// { value: 1, done: false }console.log(gen2.throw(50));// throw called with 50// { value: 'gf return value', done: true }console.log(gen.next(60));// { value: undefined, done: true }; gen is already closed

If thereturn()/throw() method of the underlying iterator returnsdone: false, the current generator continues executing andyield* continues to delegate to the underlying iterator.

js
const iterable = {  [Symbol.iterator]() {    let count = 0;    return {      next(v) {        console.log("next called with", v);        count++;        return { value: count, done: false };      },      return(v) {        console.log("return called with", v);        return { value: "iterable return value", done: false };      },    };  },};function* gf() {  yield* iterable;  return "gf return value";}const gen = gf();console.log(gen.next(10));// next called with undefined// { value: 1, done: false }console.log(gen.return(20));// return called with 20// { value: 'iterable return value', done: false }console.log(gen.next(30));// { value: 2, done: false }; gen is not closed

If the underlying iterator doesn't have athrow() method and the generator'sthrow() is called,yield* throws an error.

js
const iterable = {  [Symbol.iterator]() {    let count = 0;    return {      next(v) {        count++;        return { value: count, done: false };      },    };  },};function* gf() {  yield* iterable;  return "gf return value";}const gen = gf();gen.next(); // First next() starts the yield* expressiongen.throw(20); // TypeError: The iterator does not provide a 'throw' method.

Specifications

Specification
ECMAScript® 2026 Language Specification
# sec-generator-function-definitions-runtime-semantics-evaluation

Browser compatibility

See also

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp