ECMAScript 6 のドラフト仕様は、現代の JavaScript 開発者にとってすでに多くの喜びをもたらしています。以前の投稿では、新しいコレクション クラスと for..of
反復ループについて説明しています。この投稿では、for..of
ループと密接に関連するジェネレータ関数について説明します。
ジェネレータを使用する理由と方法を説明した優れた資料のホストがすでに公開されています。簡単に言うと、ジェネレータはイテレータを作成する特別な関数で、イテレータは next()
メソッドを持つオブジェクトで、値を取得するために呼び出すことができます。ジェネレータ関数内でキーワード yield
が next()
の値を指定します。yield
を使用すると、ジェネレータ関数の実行を一時停止し、next()
が再び呼び出されるまで状態を保持します。この時点で、コードは再び開始し、別の値を yield
するまで(またはジェネレータ関数が終了するまで)継続します。ジェネレータ関数には、フィボナッチ数列の数値を反復するために使用するなど、正規のユースケースがいくつかあります。
では、ジェネレータの使い方のコツや問題点をいくつか取り上げた JavaScript サンプルを使って、基本的なことを詳しく見ていきましょう。随所にコメントが広がっているので、読む前にコードのライブ バージョンを試してみることができます。
では、このコードから重要なポイントをいくつか見ていきましょう。
まず、ジェネレータを作成すると、固有の状態を持つ一意のイテレータが生成されます。ジェネレータ コンストラクタにパラメータを渡すことで、動作を制御できます。
2 つ目は、イテレータの next()
メソッドを呼び出すときにパラメータを渡すことができます。これにより、その値が前回のイテレータ呼び出しの yield
ステートメントの左側に割り当てられます。これはイテレータの出力を変化させる優れた方法です。ここでは、出力された単語が大文字かどうかを制御します。生成される最初の値に影響を与えるには、ジェネレータのコンストラクタのパラメータを使用します。
最後に、ジェネレータは有限または無限のイテレータを生成できます。無限イテレータを使用する場合は、値 yield
に基づくなんらかの終了条件があることを確認してください。特に反復処理に for..of
を使用すると、誤って無限ループを記述しやすくなります。next()
の呼び出しを介して有限イテレータを使用している場合は、返されたオブジェクトの .done
プロパティによって、反復処理が完了したかどうかのシグナルとなります。
このサンプルとウェブ上で公開されている他のリソースを参考にして、独自のコードでジェネレータを使用する方法を考えるきっかけになれば幸いです。Firefox のバージョン 31 以降と Chrome のバージョンは 39 以降で、ジェネレータをネイティブにサポートしています。Regenerator プロジェクトでは、他のブラウザ用のジェネレータ サポートが提供されており、Traceur を使用することもできます。
この記事のレビューに協力してくれた Erik Arvidsson に感謝します。