Iterator() コンストラクター
Baseline
2025
Newly available
Since March 2025, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Iterator() コンストラクターは、イテレーターを作成する他のクラスのスーパークラスとして意図通りに使用されることを目的としています。これ自体で構築された場合、エラーが発生します。
構文
new Iterator()
引数
なし。
返値
新しい Iterator オブジェクトです。
例外
TypeError-
new.targetがIterator関数事態に呼び出された場合、つまり、Iteratorコンストラクターそれ自身が構築された場合。
解説
Iterator は抽象クラスを表します。抽象クラスとは、サブクラスに対して指定された共通のユーティリティを提供するクラスですが、それ自体がインスタンス化されることを意図していません。これは、他にもイテレータークラスのスーパークラスであり、特定の反復処理アルゴリズムを実装するサブクラスを作成するために使用されます。つまり、 Iterator のすべてのサブクラスは、イテレータープロトコルで要求されるように、 next() メソッドを実装する必要があります。 Iterator は実際には next() メソッドを提供していないため、 Iterator を直接構築することは意味がありません。
また、 Iterator.from() を使用して、既存の反復可能オブジェクトまたはイテレーターオブジェクトから Iterator のインスタンスを作成することもできます。
例
>Iterator のサブクラス化
次の例では、反復処理が可能なカスタムデータ構造である Range を定義しています。オブジェクトを反復処理可能にするには、ジェネレーター関数という形で [Symbol.iterator]() メソッドを提供します。
class Range {
#start;
#end;
#step;
constructor(start, end, step = 1) {
this.#start = start;
this.#end = end;
this.#step = step;
}
*[Symbol.iterator]() {
for (let value = this.#start; value <= this.#end; value += this.#step) {
yield value;
}
}
}
const range = new Range(1, 5);
for (const num of range) {
console.log(num);
}
これはうまく動作しますが、組み込みのイテレーターの作業方法ほど優れてはいません。 2 つの問題があります。
- 返されたイテレーターは
Generatorを継承しており、これはGenerator.prototypeへの変更が返されたイテレーターに影響することを意味しており、抽象化の漏れです。 - 返されたイテレーターはカスタムプロトタイプを継承しないため、イテレーターに追加のメソッドを意図通りに追加するのが難しくなります。
Iterator をサブクラス化することで、組み込みのイテレーター(例えば、マップのイテレーター)の実装を模倣することができます。これにより、 [Symbol.toStringTag] などの追加のプロパティを定義することができ、返値のイテレーターにおいてイテレーターのヘルパーメソッドを利用できるようになります。
class Range {
#start;
#end;
#step;
constructor(start, end, step = 1) {
this.#start = start;
this.#end = end;
this.#step = step;
}
static #RangeIterator = class extends Iterator {
#cur;
#s;
#e;
constructor(range) {
super();
this.#cur = range.#start;
this.#s = range.#step;
this.#e = range.#end;
}
static {
Object.defineProperty(this.prototype, Symbol.toStringTag, {
value: "Range Iterator",
configurable: true,
enumerable: false,
writable: false,
});
// Avoid #RangeIterator from being accessible outside
delete this.prototype.constructor;
}
next() {
if (this.#cur > this.#e) {
return { value: undefined, done: true };
}
const res = { value: this.#cur, done: false };
this.#cur += this.#s;
return res;
}
};
[Symbol.iterator]() {
return new Range.#RangeIterator(this);
}
}
const range = new Range(1, 5);
for (const num of range) {
console.log(num);
}
サブクラス化パターンは、多数の独自のイテレーターを作成したい場合に便利です。 Iterator を継承していない反復可能オブジェクトやイテレーターオブジェクトがあり、そのオブジェクトにイテレーターのヘルパーメソッドを呼び出したいだけの場合、 Iterator.from() を使用して、一時的に Iterator インスタンスを作成することができます。
仕様書
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-iterator-constructor> |