反復可能オブジェクトを定義するプロトコル
// ── イテレーターとは: next() メソッドで値を順に取り出す仕組み
// { value: 値, done: 完了したか } を返す next() を実装する
// ── カスタムイテレーターを作る ────────────────────────
function createRange(start: number, end: number) {
let current = start;
return {
// next() を呼ぶたびに次の値を返す
next() {
if (current <= end) {
return { value: current++, done: false }; // まだ続く
}
return { value: undefined, done: true }; // 完了
},
// [Symbol.iterator] を実装すると for...of が使えるようになる
[Symbol.iterator]() { return this; }
};
}
const range = createRange(1, 3);
console.log(range.next()); // { value: 1, done: false }
console.log(range.next()); // { value: 2, done: false }
console.log(range.next()); // { value: 3, done: false }
console.log(range.next()); // { value: undefined, done: true }
// for...of でも使える
for (const n of createRange(1, 5)) {
console.log(n); // 1, 2, 3, 4, 5
}
// ← ジェネレーター関数を使うと同じことを簡単に書ける
function* range2(start: number, end: number) {
for (let i = start; i <= end; i++) yield i;
}Array・Map・Set・String・NodeListはイテラブル。Symbol.iteratorを実装することでfor...ofやスプレッドが使えるようになる。