yield*

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.

**Выражение yield* **используется для того, чтобы "передать управление" функцией-генератором другому генератору или итерируемому объекту.

Синтаксис

 yield* [[expression]];
expression

Итерируемый объект

Описание

Выражение yield* в функции-генераторе принимает итерируемый объект и возвращает его значения по очереди, как если бы эта функция-генератор возвращала их сама.

Значение выражения yield* само по себе равно последнему значению итерируемого объекта (т.е., того когда done равно true).

Примеры

Передача другому генератору

В следующем примере, значения полученные из g1() возвращаются из g2 вызовами next, как будто бы она вычислила их сама.

js
function* g1() {
  yield 2;
  yield 3;
  yield 4;
}

function* g2() {
  yield 1;
  yield* g1();
  yield 5;
}

var iterator = g2();

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: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

Другие итерируемые объекты

Помимо объектов генераторов, yield* может перебирать другие виды итерируемых объектов, т.е. массивы, строки, объекты аргументов и др.

js
function* g3() {
  yield* [1, 2];
  yield* "34";
  yield* Array.from(arguments);
  // Определение этого итератора ниже
  yield* new PowesOfTwo(4);
}

var iterator = g3(5, 6);

// Значения из массива
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: "4", done: false }
// Из аргументов
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
// Из специального итератора
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 4, done: false }

console.log(iterator.next()); // { value: undefined, done: true }

// Итератор, который возвращает все степени двойки
// до maximum включительно
class PowersOfTwo {
  constructor(maximum) {
    this.maximum = maximum;
    this.value = 1;
  }
  [Symbol.iterator]() {
    const self = this;
    return {
      next() {
        if (self.value > self.maximum) return { done: true };

        const value = self.value;
        self.value *= 2;
        return { done: false, value };
      },
    };
  }
}

Собственное значение выражения yield*

yield* - это выражение, а не оператор, поэтому оно имеет значение, равное последнему значению итератора

js
function* g4() {
  yield* [1, 2, 3];
  return "foo";
}

var result;

function* g5() {
  result = yield* g4();
}

var iterator = g5();

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 },
// g4() в этой точке вернёт { value: "foo", done: true }

console.log(result); // "foo"

Спецификации

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

Совместимость с браузерами

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
yield*

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
See implementation notes.

Специфичные для Firefox примечания

  • Начиная с Gecko 33, разбор выражений yield было приведено к соответствию с последними спецификациями ES6 (Firefox bug 981599):

    • Реализована корректная обработка разрыва строки. Разрыва строки между "yield" и "*" быть не может. Такой код вызовет SyntaxError:

      js
      function* foo() {
        yield
        *[];
      }
      

Смотрите также