Thanks to visit codestin.com
Credit goes to developer.mozilla.org

This page was translated from English by the community. Learn more and join the MDN Web Docs community.

View in English Always switch to English

yield*

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since сентябрь 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® 2027 Language Specification
# sec-generator-function-definitions-runtime-semantics-evaluation

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

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

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

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

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