JavaScriptでイテレータ(反復処理)を扱う際に、「TypeError: xxx is not iterable」というエラーに遭遇したことはありませんか?このエラーは、反復可能ではないオブジェクトに対して`for...of`ループなどを使用しようとした際に発生します。

今回は、このエラーを解決する方法として、`Symbol.iterator`の使い方について詳しく解説します。

エラーが発生する状況

以下のようなコードを実行すると、エラーが発生します:

const customObject = {
  data: [1, 2, 3]
};

for (const item of customObject) {
  console.log(item);
}
// TypeError: customObject is not iterable

Symbol.iteratorを使った解決方法

このエラーを解決するには、オブジェクトに`Symbol.iterator`メソッドを実装します:

const customObject = {
  data: [1, 2, 3],
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.data.length) {
          return { value: this.data[index++], done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

for (const item of customObject) {
  console.log(item); // 1, 2, 3が順番に出力される
}

Symbol.iteratorの仕組み

`Symbol.iterator`メソッドは、以下の要素を含むイテレータオブジェクトを返す必要があります:

  • `next()`メソッド
  • `next()`が返すオブジェクト(`value`と`done`プロパティを持つ)

実践的な使用例

カスタムコレクションクラスを作成する例:

class Collection {
  constructor() {
    this.items = [];
  }

  add(item) {
    this.items.push(item);
  }

  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.items.length) {
          return { value: this.items[index++], done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
}

const collection = new Collection();
collection.add('Apple');
collection.add('Banana');
collection.add('Orange');

for (const item of collection) {
  console.log(item); // Apple, Banana, Orangeが順番に出力される
}

イテレータの便利な使用方法

`Symbol.iterator`を実装したオブジェクトは、以下のような機能も利用できます:

  • スプレッド演算子
const array = [...customObject];
  • 配列の分割代入
const [first, second] = customObject;

まとめ

`Symbol.iterator`を使用することで、カスタムオブジェクトを反復可能にできます。これにより:

  • `for...of`ループが使用可能になる
  • スプレッド演算子が使用可能になる
  • 分割代入が使用可能になる

これらの機能を活用することで、より柔軟なデータ構造を実装できます。

以上の実装方法を理解することで、JavaScriptでのイテレータ関連のエラーを効果的に解決できます。