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年9月.
yield 演算子は、ジェネレーター関数を一時停止したり再開したりするために使用します。
試してみましょう
function* foo(index) {
while (index < 2) {
yield index;
index++;
}
}
const iterator = foo(0);
console.log(iterator.next().value);
// 予想される結果: 0
console.log(iterator.next().value);
// 予想される結果: 1
構文
yield
yield expression
引数
expression省略可-
イテレータープロトコル経由でジェネレーター関数が生成する値を定義します。省略した場合、代わりに
undefinedが生成されます。
返値
ジェネレーターの next() メソッドに渡されたオプションの値を返し、その実行を再開します。
メモ:
つまり、next() は非対称です。常に値を現在中断されている yield に送信しますが、次の yield のオペランドを返します。最初の next() 呼び出しに渡された引数は、現在中断されている yield が存在しないため取得できません。
解説
yield キーワードは、ジェネレーター関数の実行を一時停止し、ジェネレーターの呼び出し元に yield キーワードに続く値を返します。これは、 return キーワードのジェネレーター版と考えることができます。
yield はそれを含むジェネレーター関数の中で直接呼び出すことしかできません。呼び出し先の関数から呼び出すことはできません。
ジェネレーター関数を呼び出すと、Generator オブジェクトが構築されます。このジェネレーターの next() メソッドが呼び出されるたびに、ジェネレーターは実行を再開し、次のいずれかに達するまで実行を続けます。
yield式。この場合、ジェネレーターは一時停止し、next()メソッドは、イテレーター結果オブジェクトを返します。このオブジェクトには、valueとdoneの 2 つのプロパティがあります。valueプロパティはyield演算子の後にある式の値であり、doneはfalseで、ジェネレーター関数が完全に終了していないことを示します。- ジェネレーター関数の終了。この場合、ジェネレーターの処理が終了し、
next()メソッドはイテレーター結果オブジェクトを返します。このオブジェクトではvalueがundefined、doneがtrueとなります。 return文。この場合、ジェネレーターの処理は終了し、next()メソッドはイテレーター結果オブジェクトを返します。このオブジェクトでは、valueが指定された返値となり、doneはtrueとなります。throw文。これは、ジェネレーターの実行が完全に停止し、next()メソッドは指定された例外を発生します。
yield 式で一時停止すると、ジェネレーターのコード実行は、ジェネレーターの next() メソッドが再度呼び出されるまで停止したままになります。ジェネレーターの next() メソッドにオプションの値が渡された場合、その値はジェネレーターの現在の yield 操作によって返される値となります。最初の next() 呼び出しには、対応する中断された yield 操作が持たないため、最初の next() 呼び出しで渡された引数を取得する方法はあり��せん。
ジェネレーターの return() または throw() メソッドが呼び出された場合、 return 文または throw 文が一時停止した yield 式で実行されたかのように動作します。ジェネレーター関数本��内で try...catch...finally を使用することができます。 return() または throw() メソッドが呼び出された場合、保留中の yield 式が存在しない場合(next() がまだ呼び出されていないか、ジェネレーターが既に完了しているため)、早期完了は処理できず、ジェネレーターは常に終了します。
例
yield の使用
次のコードはジェネレーター関数の定義例です。
function* countAppleSales() {
const saleList = [3, 7, 5];
for (const sale of saleList) {
yield sale;
}
}
ジェネレーター関数が定義されると、ご覧のようにイテレーターを構築するために使用されます。
const appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }
ジェネレーターには next(value) で値を渡すこともできます。step は yield 式の返値として評価します。ただし、next() が最初の時点で呼び出された際にジェネレーターの next() メソッドに渡された値は無視されます。
function* counter(value) {
while (true) {
const step = yield value++;
if (step) {
value += step;
}
}
}
const generatorFunc = counter(0);
console.log(generatorFunc.next().value); // 0
console.log(generatorFunc.next().value); // 1
console.log(generatorFunc.next().value); // 2
console.log(generatorFunc.next().value); // 3
console.log(generatorFunc.next(10).value); // 14
console.log(generatorFunc.next().value); // 15
console.log(generatorFunc.next(10).value); // 26
仕様書
| Specification |
|---|
| ECMAScript® 2027 Language Specification # prod-YieldExpression |