JavaScriptの言語仕様に新しく追加される予定の「Iterator Helpers」について解説します。
Iterator Helpers Proposalについて
JavaScriptの言語仕様に、イテレータを操作するための便利なメソッドを追加しようという提案です。
2024年9月現在Stage3であり、今のところまだ全てのブラウザやランタイムで利用できるわけではありません。
この機能を使うと、配列操作を遅延評価することができます。
配列操作の遅延評価とは
従来のJavaScriptの配列操作関数では、メソッドを呼び出した瞬間に配列操作が走っていました。
// .map()を呼び出すと、即時関数で渡した関数がすぐに実行され、結果の配列が作成される
const result = [0, 1, 2]
.map(val => val + 1)
.map(val => val ** 2);
一方、計算処理をすぐに行い結果の配列を先に生成するのではなく、実際に結果が必要になる時まで計算処理が延期させることを、遅延評価といいます。
▲i番目の結果が必要になった時に初めて(val + 1) ** 2
の計算が走る
JavaScriptでライブラリを使わずに遅延評価する
こちらのメソッドは2024年9月現在、Chrome、Node.js、Deno、FirefoxのTechnology Preview版で利用できます。Safariではまだ利用できません。
配列に対して.values()
メソッドを使うとIterator
オブジェクトに変換できます。
このIterator
オブジェクトに対して.map()
などのメソッドを使うと、遅延評価になります。
また、Iterator
オブジェクトの.toArray()
メソッドを使うと、配列に戻すことができます。
const result = [0, 1, 2]
+ .values()
.map(val => val + 1)
.map(val => val ** 2)
+ .toArray();
例:無限イテレータ
通常の配列操作の場合、無限の長さを持つ配列は扱えません(当然ですね)。
一方、Iterator
オブジェクトを使って遅延評価を行う場合は、無限に値を取り出せるイテレータを作って操作することができます。
今回は無限イテレータを作成しmap
で変換したのち、take
メソッドを使って先頭3個を取り出すコードを書いてみましょう。
// 無限イテレータを作成する関数
function* infinityIterator() {
let i = 0;
while (true) {
yield i++;
}
}
infinityIterator() // 無限イテレータを生成
.map(val => val + 1)
.map(val => val ** 2)
.take(3) // 先頭3個を取り出し
.toArray(); // [1, 4, 9]
これがもし配列なら、1回目のmapの際に無限ループに陥り、プログラムが止まらなくなってしまうはずです。
しかし、イテレータは遅延評価されるという性質があるため、最後に.take(3)
で先頭3個を取り出せば、後ろの4番目以降の値については計算されず、無限ループを回避できます。
このように、Iterator
オブジェクトを使って遅延評価することで、無駄な計算処理を省くことができます。また、中間配列の生成を避けることができるため、処理の高速化も期待できます。
まとめ
- JavaScriptで配列の遅延評価ができる「Iterator Helpers」がもうすぐ導入予定
- 「Iterator Helpers」を使って配列操作を遅延評価するには、
.values()
でIterator
オブジェクトに変換する - 遅延評価することで、不要な計算を回避したり、中間配列の生成を避けることができたりといったメリットがある
Iteratorオブジェクトには、今回紹介したmap
やtake
以外にも、便利なメソッドが揃っています。導入が待ち遠しいですね!
関連記事