なっく日報

技術やら生活やらのメモ

yield*って何?

ESLintの↓のルールで初めて知ったのですが、

eslint.org

yield*について調べてみました。

何?

developer.mozilla.org

によれば

The yield expression iterates over the operand and yields each value returned by it. The value of yield expression itself is the value returned by that iterator when it's closed (i.e., when done is true).

具体例

コードで見た方が早いかと思います。

別のジェネレータに委譲

function* g1() {
  yield 2;
}

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

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: undefined, done: true }

他の反復可能なオブジェクトをyieldできる

function* g3() {
  yield* [1, 2];
  yield* "34";
  yield* arguments;
}

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: undefined, done: true }

配列っぽいもの iterableなモノはとりあえずいけるイメージ。

yield*式自体の値

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() returned { value: "foo", done: true } at this point

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

g4()の戻り値が↑のタイミングで最終的にresultに入ると。

使い道

うーむ、ぱっと思いつかない・・・

※追記:Everything is Iterator 読んでちゃんと考えよう。