回せないものを、回そうとしたときに出ます。
for (const value of { a: 1, b: 2 }) {
console.log(value);
}素のオブジェクトはfor...of で回せません。
{(intermediate value)} は「その場で書いたオブジェクト」という意味です。変数に入れて渡すと、代わりに変数の名前が出ます。
どこで出るか
for...of だけではありません。同じ仕組みを使う場所すべてで出ます。
const list = null;
for (const value of list) {
console.log(value);
}| 書き方 | 例 |
|---|---|
for...of |
for (const x of value) |
| スプレッド | [...value] / f(...value) |
| 配列の分割代入 | const [a] = value |
Array.from() / new Set() / new Map() |
new Set(value) |
Promise.all() |
Promise.all(value) |
Symbol.iterator を持っているかどうかだけで決まります。
→ 反復可能とイテレータ
原因1: 素のオブジェクトを回そうとした
いちばん多い原因です。
| 欲しいもの | 使うもの |
|---|---|
| 鍵だけ | Object.keys() |
| 値だけ | Object.values() |
| 両方 | Object.entries() |
→ Object.keys() / values() / entries()
for...in でも回せますが、受け継いだ鍵まで拾うので勧めません。
原因2: null や undefined が来た
const response = { items: [1, 2], total: 2 };
console.log([...response]);文言に出るのは、書いた名前であって中身ではありません。
list が null なのか、素のオブジェクトなのかは、これだけでは分かりません。
まず中身を出してください。
const fake = { length: 2, 0: 'a', 1: 'b' };
console.log([...fake]);null や undefined だったなら、
回せない形なのではなく、値がまだ入っていないという意味です。
出どころをたどってください。 通信の失敗、まだ届いていない、鍵の綴り違い。
その場で凌ぐなら、空配列に倒します。
const point = { x: 1, y: 2 };
const [x, y] = point;ただし、これは原因を隠す書き方でもあります。 「無いのが正常」なときにだけ使ってください。 → Cannot read properties of undefined
原因3: 配列だと思っていたものが違った
通信の結果は、中に包まれていることがよくあります。
response ではなく response.items が配列です。
まず中身を出して確かめてください。
原因4: length があるだけの形
length を持っていても、回せるとは限りません。
Array.from() なら扱えます。
→ Array.from() / Array.of() / new Array()
ブラウザの NodeList や HTMLCollection は、いまはどちらでも扱えます。古い環境向けの記事で Array.prototype.slice.call() を見かけますが、いま書く必要はありません。
原因5: オブジェクトを分割代入で受けた
角括弧と波括弧を取り違えています。
[ ]… 並びから順番に取り出す(配列){ }… 名前で取り出す(オブジェクト)
自分で回せるようにする
どうしてもそのオブジェクトを回したいなら、Symbol.iterator を持たせます。
ただし、ふつうは Object.entries() で足ります。
自作するのは、独自の順序や終わりの条件があるときだけにしてください。
探しかたの順序
- 文言に出ている名前を探す。それが中身を教えてくれるわけではない
- その値を
console.log()とtypeofで出すnull/undefinedだった → 値の出どころを疑う。回し方の問題ではない- 素のオブジェクトだった →
Object.entries()を挟む - 中に配列が入っていた → そちらを渡す
- 分割代入なら、
[ ]と{ }を見直す
このページの実行結果は Node 22.22.3 のものです。文言は処理系と版によって変わります。自分の環境で出た文言で検索してください。
まとめ
- 出るのは
for...of・スプレッド・配列の分割代入・new Set()など - 判定はSymbol.iterator を持つかだけ
- 素のオブジェクトは回せない。
Object.entries()を挟む - 文言に出るのは書いた名前で、中身ではない。 まず値を出して見る
- 値が
null/undefinedだったなら、出どころの問題 lengthがあるだけの形はArray.from()で扱う[ ]と{ }の取り違えでも出る