for-in でオブジェクトを走査する
for-in でオブジェクトを走査する とは
オブジェクトのキーを順番に取り出せる
for-in文を学び、値の合計を求める関数を書いてみよう。
for-in はオブジェクトのキーを順番に取り出すループ
前のレッスンでは配列向けの for-of を学びました。今度はオブジェクト向けのループ、for-in を学びます。{ name: 'Alice', age: 30 } のようなオブジェクトの キー (プロパティ名) を順番に取り出すための構文です。
JavaScriptのオブジェクトはキーと値の集まりで、Pythonの辞書 (dict) やJavaのMapに相当します。配列が「順番が大事なデータの並び」なら、オブジェクトは「名前で値を引くデータ」です。例えばユーザー情報{ name: 'Alice', age: 30, city: 'Tokyo' }のように、各値にラベル (キー) が付いています。
オブジェクトの中身を 1 つずつ見たいとき、for-of は使えません。なぜなら普通のオブジェクトは iterable (反復可能) ではない からです。代わりに for-in を使います。
JavaScript
const scores = { math: 80, english: 90, science: 70 };
for (const subject in scores) {
// subject に 'math', 'english', 'science' が順に入る
}ループの中で subject (キー) から値を取り出すには、scores[subject] のように ブラケット記法 を使います。
JavaScript
const scores = { math: 80, english: 90, science: 70 };
let total = 0;
for (const subject in scores) {
total += scores[subject];
}
// total は 240for-in 文の文法
JavaScript の for-in 文の基本形は次のとおりです。
JavaScript
for (const キー in オブジェクト) {
// キーを使った処理
}大事なポイントは次の通りです。
inキーワード を使う (ofではない、混同しないように)- 左辺の 変数にはキー (プロパティ名) が文字列で入る
- 値そのものは入らない ので、
obj[key]で取り出す必要がある for-ofと違って、これは オブジェクト専用 と思っておくとよい
JavaScriptのオブジェクトのキーは原則として 文字列 (またはSymbol) です。数値を書いても自動的に文字列に変換されます。なのでfor-inで取り出されるキーは常に文字列型だと覚えておきましょう。
for-in と for-of の違い
初心者が一番混乱するのが for-in と for-of の違いです。次の表で整理してみます。
JavaScript
const arr = ['a', 'b', 'c'];
// for-in は インデックス (文字列) を取る
for (const i in arr) {
// i は '0', '1', '2'
}
// for-of は 値そのものを取る
for (const v of arr) {
// v は 'a', 'b', 'c'
}配列にも for-in は使えてしまうのですが、インデックスが文字列で返ってくる うえに、配列のプロトタイプに追加されたプロパティまで拾ってしまう可能性があり、推奨されません。配列は for-of か通常の for、オブジェクトは for-in、これを鉄則にしましょう。
Object.keys や Object.entries との比較
モダンな JavaScript ではオブジェクトを走査するとき、for-in よりも Object.keys や Object.entries を使う流派も増えています。
JavaScript
const scores = { math: 80, english: 90, science: 70 };
// Object.keys でキーの配列を取得 → for-of で回す
for (const key of Object.keys(scores)) {
// key にキーが入る
}
// Object.entries で キーと値のペアを取得
for (const [key, value] of Object.entries(scores)) {
// key と value が両方手に入る
}メリットは、配列を経由するので Array.filter や Array.map と組み合わせやすい ことと、プロトタイプチェーンを辿らないので 安全 だということです。for-in を使うか、Object.keys / Object.entries を使うかは好みですが、新規コードでは後者を選ぶ人が増えています。
実行フローを図で追ってみる
for (const key in obj) のループの流れは次の通りです。
通常の for のような「初期化・条件・更新」ではなく、「次のキーを取って、あれば本体実行、なければ終了」というシンプルな流れです。
よくある間違い
for-in 文を使い始めるとき、初心者がハマる落とし穴が 3 つあります。
- 値が直接入ると勘違い —
for (const score in scores) { total += score; }のように書くと、scoreには キー (文字列) が入っているので、'math' + 0 = 'math'のような文字列連結になってしまいます。値が欲しいときは必ずscores[score]で取り出しましょう - 配列に
for-inを使う — 動作はするのですが、インデックスが文字列で返ってくるうえ、プロトタイプの汚染にも弱いので非推奨です。配列はfor-ofか通常のforを使いましょう ofとinを取り違える —for (const x of obj)と書くと普通のオブジェクトではTypeErrorが出ます (iterable ではないため)。逆にfor (const i in arr)だとインデックスが文字列で返るのが分かりにくくバグの温床です
for-inは 継承されたプロパティ も列挙してしまうという落とし穴があります。本格的なプロダクションコードではObject.prototype.hasOwnProperty.call(obj, key)でフィルタする、もしくは初めからObject.keysを使うのが安全です。今回の課題ではオブジェクト直下のプロパティしか扱わないので気にしなくて OK ですが、頭の片隅に入れておきましょう。
もうひとつ、for-in のループの順序は 挿入順 が原則になっています (ES2015 以降)。{ a: 1, b: 2, c: 3 } を回すと a, b, c の順でキーが返ります。古いブラウザでは順序が保証されないこともありましたが、最近の JavaScript では安心して使えます。
やってみよう
それでは今回の課題に取り組みましょう。やることは次の通りです。
sumValues(obj)関数の中身を埋めるfor-in文を使ってオブジェクトobjの全ての値を合計して返すsumValues({ a: 1, b: 2, c: 3 })が6、sumValues({ x: 10, y: 20 })が30、sumValues({})が0になるかを確認する
ヒントとして、合計用変数 total を 0 で初期化し、for (const key in obj) でキーを回し、total += obj[key]; で値を加算します。最後に return total; を忘れないようにしましょう。
余裕があれば、Object.values(obj).reduce((a, b) => a + b, 0) のような高階関数版でも書いてみてください。for-in だけでなく、Object.keys Object.values Object.entries の使い方も覚えると、オブジェクト処理の引き出しが広がります。
この先のレッスンでは break continue のループ制御や、ネストしたループ、素数列挙のような少し応用的なループへと進んでいきます。for-in はオブジェクトを扱う上で基礎中の基礎なので、ぜひ手を動かして覚えましょう。
よくある質問
Q. ブラウザと Node.js で動作は変わりますか?
A. JavaScript の構文・組み込み機能(配列・文字列・Promise 等)はどちらでも同じです。違いは DOM API(ブラウザ専用)と fs などのファイル系(Node 専用)など、実行環境固有の機能です。コアロジックは両方で動くため、テストもしやすくなります。
Q. ES6 以降の新機能は使っても大丈夫ですか?
A. 現代のブラウザ・Node.js は ES2020 以降の機能をほぼサポートしています。古い IE 等を対象にする必要が無ければ、let/const、アロー関数、分割代入、async/await を積極的に使ってください。トランスパイル(Babel/Vite)が必要なケースは年々減っています。
Q. TypeScript に進む価値はありますか?
A. 型情報があるとリファクタやエディタ補完が劇的に効くため、規模が大きくなるなら TypeScript への移行を強くおすすめします。最初は any を許容しつつ徐々に型を付ければ、JS の知識をそのまま活かせます。
次のレッスン
次は break と continue でループを制御する で、オブジェクトのキーを順番に取り出せる for-in 文を学び、値の合計を求める関数を書いてみよう を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- for-in の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. for-in とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- 関数名は
sumValues、引数はオブジェクトobj1 つ、戻り値は数値 - 繰り返し処理には必ず
for-in文を使うこと (Object.valuesやreduceではなく) - 値はすべて数値であることを前提としてよい
入出力例
test-cases.txt
sumValues({"a":1,"b":2,"c":3}) → 6
sumValues({"x":10,"y":20}) → 30
sumValues({}) → 0
sumValues({"english":90,"math":80,"science":70}) → 240