はじめに
おいおい、JavaScriptやってるのにイテラブル知らないなんて、配列ばっかfor文で回して疲れてんの? 笑
まあ、ES6から本格的に入ってきた機能だから、知らなくても生きていけるけど、知ったら世界が変わるよ。for…ofループとかスプレッド演算子とか、めっちゃ便利になるからさ。
まず、イテラブルとは何ぞや?
イティセル/コード専門官JavaScriptのイテラブル(Iterable)とは、順番に要素を取り出せるオブジェクトのこと。簡単に言うと、「for…ofでループできるやつ」だよ。
- 配列(Array)
- 文字列(String)
- Map
- Set
- NodeList(DOMの要素集合)
これらはデフォルトでイテラブル。普通のオブジェクト({})はデフォルトじゃイテラブルじゃないんだよね。なんで? だってオブジェクトはキー順が保証されてない古い仕様だからさ(笑)。
MDNによると、イテラブルはSymbol.iteratorっていう特殊なプロパティを持ってて、それがイテレーターを返す関数になってるオブジェクトだよ。
イテレーター(Iterator)って何?
イテレーター:「はい、次の方〜!」



イテラブル(配列とか)が「客が並んでる行列」だとしたら、イテレーターは「窓口の係員」だ。
この係員(イテレーター)は、next() というボタンを押されるたびに、機械的にこう対応する。
- 客(値)を一人通す。
- 「まだ後ろに誰かいますか?」という旗(フラグ)を振る。
こいつの返事は常にこの 決まり文句(オブジェクト) だけだ。
// next() を呼ぶと...
{ value: '客A', done: false }
// 「はい、客Aさんどうぞ。あ、まだ後ろ並んでますね(done: false)」
{ value: '客B', done: false }
// 「はい、客Bさんどうぞ。まだいますね(done: false)」
{ value: undefined, done: true }
// 「...え? もう誰もいませんよ? 閉店です(done: true)」


ここがポイントだよ
value: お目当てのモノ(中身)。done: 「もう終わり? まだある?」 という終了合図。
done: true になったら、何度 next() を呼んでも 「いや、だから無いって! 帰れよ!」 ({ value: undefined, done: true })と言い続ける。頑固なやつなんだよ。
for…ofループでどう使うの?



はい、来ました。イテラブル界の「全自動ベルトコンベア」こと for...of ループ先輩の登場です。
古臭い for (let i = 0; ...) とかいう「手動カウンター」は窓から投げ捨てろ! for...of は、「中身をよこせ、話はそれからだ」という非常に直感的で、かつ強欲なループです。
1. 配列(Array)の場合
「回転寿司の皿を全部食う」イメージです。インデックス(何番目か)なんてどうでもいい。ネタ(値)だけをよこせ。
const arr = ['あ', 'い', 'う'];
// 翻訳:「arr の中から、順番に item という皿に取り出して食う」
for (const item of arr) {
console.log(item);
}出力結果
あ
い
うポイント: >
itemはただの変数名です。sushiでもyatsuraでも何でもOK。
2. 文字列(String)の場合
文字列を for...of に突っ込むと、「千切り(スライス)」にされます。
// 文字列だって「文字の並び」だろ? バラバラにしてやるよ!
for (const char of 'JavaScript') {
console.log(char);
}出力:
J
a
v
...(中略)...
t狂気: > 昔は
.split('')とかやって配列にして回してましたが、今はそのまま放り込めばOK。楽すぎて脳が退化しそうです。
3. ここが重要! vs for...in



ここテストに出ます。というか、ハマって泣く人が続出します
for...of(今回の主役)- 「中身(値)」 を持ってくる。
- 優秀なウェイター。 「ハンバーグお持ちしました」
for...in(紛らわしい悪魔)- 「キー(インデックスやプロパティ名)」 を持ってくる。
- 空気読めない客。 「メニューの3番目の項目!」(いや中身言えよ)
const list = ['A', 'B', 'C'];
// for...in の罠(インデックスが返ってくる)
for (const x in list) {
console.log(x);
}
// for...of の正義(値が返ってくる)
for (const x of list) {
console.log(x);
}"0", "1", "2" // ← は? お前誰?(※しかも文字列で返る)
"A", "B", "C" // ← これこれ!これが欲しかったの!for...of は、「順番があるもの(イテラブル)」なら何でも、何も考えずに中身を順番に取り出してくれる、思考停止に最適な最高のマシーンです。
MapやSetも同じノリで回せますが、まずは「配列の中身を全部見たいときは、これ一択」と覚えておけば、明日からドヤ顔でコードが書けます。
Symbol.iteratorのコード例見てみよう
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }JavaScriptにおいて、配列 [1, 2, 3] はただデータが並んでいるだけの状態です。 しかし、こいつに Symbol.iterator という「召喚魔法」を唱えると、データを一つずつ丁寧(かつ無慈悲)に渡してくれる「専任の担当者(イテレータ)」が現れます。
コードの動きを超訳するとこうなります。
1. 担当者を呼び出す
const arr = [1, 2, 3]; // 客が3人並んでる
const iterator = arr[Symbol.iterator](); // 「おい、案内係! 出てこい!」ここではまだデータは出てきません。 「案内係(イテレータ)」がシフトに入っただけです。こいつはまだ棒立ちです。
2. 1回目の尋問
console.log(iterator.next());
// 結果: { value: 1, done: false }あなた:「おい、次!」 案内係:「はい、『1』です。(まだ残業は続くので done: false です)」
3. 2回目の尋問
console.log(iterator.next());
// 結果: { value: 2, done: false }あなた:「おい、次!」 案内係:「はい、『2』です。(まだ帰れません done: false です)」
4. 3回目の尋問
console.log(iterator.next());
// 結果: { value: 3, done: false }あなた:「おい、次!」 案内係:「はい、『3』です。(次でラストなんでまだ done: false です)」
5. 最後の無慈悲な宣告
console.log(iterator.next());
// 結果: { value: undefined, done: true }あなた:「おい、次!」 案内係:「ありません!!!(value: undefined) 閉店です!!! 帰ってください!!!(done: true)」



このコードは、普段は全自動で行われる「データ渡し」を、指差し確認しながらマニュアル操作している状態です。
value: 渡されたブツ。done: 「もう店じまいしていいか?」のフラグ。falseならまだ営業中、trueならシャッターが閉まった状態。
普段何気なく使っている for (const x of arr) は、裏でこの「案内係」をこき使い、done: true になるまで next() を連打し続けているブラック企業のような仕組みなわけです。
カスタムイテラブル作ってみよう(実践編)
お前もオリジナル作れるよ。簡単だから試せ。
例: 1から10までの範囲オブジェクト
const range = {
from: 1,
to: 10,
[Symbol.iterator]() { // これが大事!
let current = this.from;
const last = this.to; // ここでthisを捕まえておくと安全
return {
next() {
if (current <= last) {
return { value: current++, done: false };
}
return { done: true };
}
};
}
};
for (const num of range) {
console.log(num); // 1から10まで出力
}無限ループ版とかも作れるけど、for…ofで回したらブラウザ死ぬから気をつけろよ(笑)。
ジェネレーター使えばもっと楽
function* generatorRange() {
for (let i = 1; i <= 10; i++) {
yield i;
}
}
for (const num of generatorRange()) {
console.log(num);
}ジェネレーターは自動でイテラブルになるんだぜ。便利すぎ。
イテラブルが使えるところ(リストアップ)
- for…of ループ
- スプレッド演算子 […] (配列展開)
- 配列分解代入 [a, b] = iterable
- Array.from(iterable)
- new Map(iterable)
- new Set(iterable)
- Promise.all(iterable) とか
非同期イテラブル(Async Iterable)もあるけど、それはまた別話。
まとめ:イテラブル知らないと損だよ
JavaScriptのイテラブルは、データ集合を統一的に扱える神機能。配列以外もfor…ofでサクサクループできるし、カスタム作れば無限の可能性。古いfor文やforEachに頼ってる人は、今日から乗り換えろよ。本当に便利だからな。










コメント