JavaScript | for…in と forEach の違い

JavaScript JavaScript
スポンサーリンク

for…inforEach はどちらも「繰り返し処理」に使えますが、性質や使いどころがかなり違います。初心者向けに整理してみましょう。


違いのまとめ

特徴for…inforEach
取り出すものキー(オブジェクトのプロパティ名 / 配列のインデックス番号)配列の値(要素)インデックス
対象オブジェクト・配列配列(や配列風オブジェクト)
書き方for (let key in obj) { ... }array.forEach((value, index) => { ... })
ループの途中で抜けられる?break / continue が使える途中で止められない(全要素を処理する)
順序オブジェクトは順序保証なし、配列はインデックス順配列の順序通りに処理される
使いどころオブジェクトのプロパティを順番に処理したいとき配列の要素を順番に処理したいとき

for…in の例(オブジェクト向け)

const scores = { math: 80, english: 70 };

for (let subject in scores) {
  console.log(`${subject}: ${scores[subject]}`);
}
// 出力:
// math: 80
// english: 70
JavaScript
  • subject にはキー(math, english)が入る
  • 値は scores[subject] で取り出す

forEach の例(配列向け)

const fruits = ["orange", "apple", "lemon"];

fruits.forEach((value, index) => {
  console.log(`${index}: ${value}`);
});
// 出力:
// 0: orange
// 1: apple
// 2: lemon
JavaScript
  • value に要素、index に番号が入る
  • 配列の順番通りに処理される

使い分けのコツ

  • オブジェクトのプロパティを回したいfor...in
  • 配列の要素を順番に処理したいforEach
  • 配列を途中で止めたいforfor...of を使う(forEach は止められない)

まとめ

  • for…in は「キーを回す」
  • forEach は「配列の値を順番に処理する」

では、配列に対する for...inforEach の違いを 見やすく可視化したサンプル を作りました。ブラウザで開くと、どちらの方法で配列を回しているかを比較できます。


配列版サンプルコード

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>for...in vs forEach 比較</title>
<style>
  body { font-family: sans-serif; }
  .box { margin-bottom: 20px; }
  h3 { margin-bottom: 5px; }
  li { margin-left: 20px; }
</style>
</head>
<body>

<div class="box">
  <h3>for...inで配列を回す場合</h3>
  <ul id="forInList"></ul>
</div>

<div class="box">
  <h3>forEachで配列を回す場合</h3>
  <ul id="forEachList"></ul>
</div>

<script>
const fruits = ['orange', 'apple', 'lemon'];

// ===== for...in =====
const ulIn = document.getElementById('forInList');
for (let index in fruits) {
  const li = document.createElement('li');
  li.textContent = "インデックス " + index + " の果物は " + fruits[index];
  ulIn.appendChild(li);
}

// ===== forEach =====
const ulForEach = document.getElementById('forEachList');
fruits.forEach(function(fruit, index) {
  const li = document.createElement('li');
  li.textContent = "インデックス " + index + " の果物は " + fruit;
  ulForEach.appendChild(li);
});
</script>

</body>
</html>
HTML

解説

1. for...in の場合

  • 配列の インデックスが文字列として取得 されます
  • 配列に不要なプロパティが追加されている場合、それも回ってしまうことがあります
  • 小規模な例では問題ないですが、実務では注意が必要です

2. forEach の場合

  • 配列の要素とインデックスを順番に取得
  • インデックスは数値
  • 配列を順番通りに回したいときはこちらが安全

見た目の違い

  • 実際にブラウザで実行すると、どちらも同じように表示されますが、内部的な扱い(インデックスの型や順序保証)が異なります
  • 大規模な配列やオブジェクトが混在する場合に差が出ます

See the Pen for…in vs forEach Comparison by MONO365 -Color your days- (@monoqlo365) on CodePen.


まとめると:

  • オブジェクト → for…in
  • 配列 → forEach または通常の for 文

では、配列に for...in を使ったときのトラブル(不要なプロパティまで回ってしまう)を アニメーションで可視化 するサンプルを作りました。

ブラウザで開くと、配列に追加した「余計なプロパティ」が for...in で回ってしまう様子をステップごとに表示します。


サンプルコード(アニメーション付き)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>for...in トラブル可視化</title>
<style>
  body { font-family: sans-serif; padding: 20px; }
  ul { list-style: none; padding-left: 0; }
  li { padding: 5px 0; }
  .highlight { background-color: #ffff99; }
</style>
</head>
<body>

<h2>for...inで配列を回すときの注意</h2>
<p>配列に追加した余計なプロパティまで回ってしまいます。</p>

<ul id="log"></ul>

<script>
const fruits = ['orange', 'apple', 'lemon'];

// 配列に余計なプロパティを追加
fruits.extra = 'not a fruit';

const log = document.getElementById('log');

let keys = [];
for (let key in fruits) {
  keys.push(key);
}

let i = 0;
function step() {
  if (i >= keys.length) return;

  const key = keys[i];
  const li = document.createElement('li');
  li.textContent = `key="${key}", value="${fruits[key]}"`;
  li.classList.add('highlight');
  log.appendChild(li);

  // アニメーション風に少しずつ追加
  setTimeout(() => {
    li.classList.remove('highlight');
    i++;
    step();
  }, 800);
}

// ステップ開始
step();
</script>

</body>
</html>
HTML

解説

  1. 配列 fruits"extra" という余計なプロパティを追加 fruits.extra = 'not a fruit';
  2. for...in で配列を回すと、通常のインデックス(0,1,2)だけでなく "extra" も含まれる
  3. アニメーションで順番に表示することで、どのキーが処理されているか視覚的に確認できる
  4. 実務では、配列は forEachfor を使う方が安全

このサンプルをブラウザで開くと、0,1,2,extra の順でアニメーション表示され、for...in が配列に向かない理由が直感で分かります。

See the Pen for…in Loop Troubleshooting Visualization by MONO365 -Color your days- (@monoqlo365) on CodePen.


では、for...inforEach の違いを 並べてアニメーションで比較できるサンプル を作ります。

ブラウザで開くと、左側に for...in、右側に forEach の処理が順番にハイライトされて表示され、配列に余計なプロパティがある場合の違いも一目で分かります。


サンプルコード(for…in vs forEach 比較アニメーション)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>for...in vs forEach アニメ比較</title>
<style>
  body { font-family: sans-serif; display: flex; gap: 50px; padding: 20px; }
  .container { width: 45%; }
  h3 { margin-bottom: 5px; }
  ul { list-style: none; padding-left: 0; border: 1px solid #ccc; padding: 10px; min-height: 120px;}
  li { padding: 5px; }
  .highlight { background-color: #ffff99; transition: background-color 0.3s; }
</style>
</head>
<body>

<div class="container">
  <h3>for...inで配列を回す</h3>
  <ul id="forInLog"></ul>
</div>

<div class="container">
  <h3>forEachで配列を回す</h3>
  <ul id="forEachLog"></ul>
</div>

<script>
const fruits = ['orange', 'apple', 'lemon'];
fruits.extra = 'not a fruit'; // 余計なプロパティ

const forInLog = document.getElementById('forInLog');
const forEachLog = document.getElementById('forEachLog');

// for...in のキーを取得
const keys = [];
for (let key in fruits) keys.push(key);

// forEach 用の配列
const arr = fruits.slice(); // 元の配列のインデックスのみ

let i = 0;
function step() {
  if (i >= keys.length && i >= arr.length) return;

  // for...in 側
  if (i < keys.length) {
    const key = keys[i];
    const li = document.createElement('li');
    li.textContent = `key="${key}", value="${fruits[key]}"`;
    li.classList.add('highlight');
    forInLog.appendChild(li);
    setTimeout(() => li.classList.remove('highlight'), 500);
  }

  // forEach 側
  if (i < arr.length) {
    const value = arr[i];
    const li = document.createElement('li');
    li.textContent = `index=${i}, value="${value}"`;
    li.classList.add('highlight');
    forEachLog.appendChild(li);
    setTimeout(() => li.classList.remove('highlight'), 500);
  }

  i++;
  setTimeout(step, 800);
}

// アニメーション開始
step();
</script>

</body>
</html>
HTML

解説

  1. for…in
    • 配列のインデックス(0,1,2)だけでなく extra も回る
    • 配列に不要なプロパティがあると予期せぬ挙動になる
  2. forEach
    • 元の配列の要素だけを順番通り処理
    • インデックスは数値
    • 安全に順番通り処理できる
  3. アニメーション
    • どの要素が処理されているかハイライトで視覚化
    • 並べて表示することで違いが一目でわかる

See the Pen for…in vs forEach Animation Comparison by MONO365 -Color your days- (@monoqlo365) on CodePen.


💡 まとめ

  • オブジェクト → for…in
  • 配列 → forEach or for
  • 配列に余計なプロパティを追加すると for...in は全部回るので注意

完全学習モードの機能

  1. オブジェクト(for…in)
    • プロパティを順番通りに表示
    • 値の種類ごとに色分け(数値は青、文字列は緑など)
  2. 配列(forEach)
    • 任意条件(偶数番目など)で表示
    • 値の種類ごとに色分け
  3. ステップ表示・アニメーション
    • 左右に並べて処理順をハイライト
    • どの時点でどの要素を処理しているか可視化

See the Pen for…in vs forEach Animation Comparison #3 by MONO365 -Color your days- (@monoqlo365) on CodePen.

このサンプルのポイント

  1. オブジェクト
    • Object.keys() を使って順番通り取得
    • 値の型に応じて色分け(数値は青、文字列は緑)
  2. 配列
    • 任意条件(偶数番目)で要素を抽出
    • 余計なプロパティは無視
    • 型ごとに色分け
  3. アニメーション
    • ステップごとにハイライトして処理の流れを可視化
    • 左右で比較できるので、どちらが安全で順序保証されるか一目で理解できる

💡 これで、初心者でも for...inforEach の使い分けや、配列・オブジェクトの扱い方を直感的に理解できる完全学習モードが完成しました。


See the Pen JavaScript Loop Learning Tool by MONO365 -Color your days- (@monoqlo365) on CodePen.

タイトルとURLをコピーしました