生成ツール - 雑念な要素

ECMAScript 6 のドラフト仕様は、すでに現代の JavaScript 開発者にとって多くの喜びをもたらしています。以前の投稿では、新しい Collections クラスと for..of の反復ループについて説明しました。この投稿では、for..of ループと密接に関連する、ジェネレータ関数について説明します。

ジェネレータを使用する理由と方法を説明した優れた資料は、すでにホストされています。簡単に言えば、ジェネレータはイテレータを作成する特別な関数で、イテレータは next() メソッドを持つオブジェクトで、このメソッドを呼び出すことで値を取得できます。ジェネレータ関数内では、キーワード yieldnext() の値を指定します。yield を使用すると、next() が再び呼び出されるまで状態が保持され、ジェネレータ関数の実行が一時停止されます。その後、コードは再び起動し、別の値 yield になるまで(またはジェネレータ関数が終了するまで)続行します。ジェネレータ関数には、フィボナッチ数列の数値を反復処理するなど、ジェネレータ関数の標準的なユースケースがいくつかあります。

基本を理解できたところで、JavaScript サンプルを使って詳細に進みましょう。ここでは、ジェネレータ操作の問題点、つまり「非常に小さい」点を取り上げています。全体にわたって多数のコメントが記載されており、読む前にライブ バージョンのコードを試すことができます。

では、このコードから重要なポイントは何でしょうか。

まず、ジェネレータを作成すると、それ自体の異なる状態を持つ一意のイテレータが生成されます。動作を制御できるジェネレータ コンストラクタにパラメータを渡すことができます。

次に、イテレータの next() メソッドを呼び出すときにパラメータを渡すことができます。その値は、前回のイテレータ呼び出しの yield ステートメントの左側に割り当てられます。これは、イテレータの出力を変化させるのに最適な方法です。ここでは、生成される単語が大文字であるかどうかをコントロールするために使用します。最初に生成される値に影響を与える場合は、ジェネレータのコンストラクタのパラメータを介して行います。

最後に、ジェネレータは有限または無限のイテレータを生成できます。無限イテレータを使用する場合は、yield の値に基づくなんらかの終了条件があることを確認してください。特に、反復処理に for..of を使用する場合は、誤って無限ループを記述してしまいがちです。next() の呼び出しを介して有限イテレータを操作する場合は、返されるオブジェクトの .done プロパティによって、反復が完了したかどうかが通知されます。

このサンプルとウェブ上で利用できる他のリソースを参考にして、ご自身のコードでジェネレータを使用する方法を考えてみてください。31 以降の Firefox と 39 以降の Chrome は、ジェネレータをネイティブにサポートしています。Regenerator プロジェクトでは他のブラウザ用のジェネレータ サポートが用意されており、Traceur を使用することもできます。

この記事のレビューに協力してくれた Erik Arvidsson に感謝します。