目次
概要
配列に格納されたデータを順に取り出して処理を行いたい場合、従来の for 文よりも簡潔で可読性の高い forEach メソッドが推奨されます。
本記事では、配列の各要素に対してコールバック関数を実行し、DOM操作やログ出力などの「副作用」を伴う処理を実装する方法を解説します。また、break が使えないといった特有の注意点についても触れます。
仕様(入出力)
forEach メソッド
配列の要素数分だけ、指定した関数(コールバック関数)を繰り返し実行します。
| 引数 | 説明 |
| callbackFn | 各要素に対して実行される関数。以下の3つの引数を受け取ります。 |
| 1. element | 現在処理されている 要素の値。 |
| 2. index | 現在処理されている要素の インデックス(0から開始)。 |
| 3. array | forEach を呼び出している 元の配列。 |
- 戻り値:
undefined(新しい配列は生成しません)。
基本の使い方
1. 要素とインデックスを取得する
配列の中身を順番にコンソールに表示する基本的な例です。
const colors = ['Red', 'Green', 'Blue'];
// 第1引数に要素、第2引数にインデックスが入る
colors.forEach((color, index) => {
console.log(`${index}: ${color}`);
});
// 出力:
// 0: Red
// 1: Green
// 2: Blue
コード全文(HTML / JavaScript)
ここでは、在庫管理システムを想定し、商品データの配列からHTMLのリストを動的に生成して画面に表示する機能を実装します。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Inventory List</title>
<style>
.inventory-panel {
font-family: sans-serif;
max-width: 500px;
border: 1px solid #ccc;
padding: 20px;
border-radius: 8px;
}
.item-row {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
}
.item-row:last-child {
border-bottom: none;
}
.stock-alert {
color: red;
font-weight: bold;
}
.stock-ok {
color: green;
}
</style>
</head>
<body>
<div class="inventory-panel">
<h3>現在の在庫状況</h3>
<div id="stock-list">
</div>
</div>
<script src="inventory.js"></script>
</body>
</html>
JavaScript
/**
* 在庫リストを表示するスクリプト
*/
// 1. データ定義(APIから取得したデータを想定)
const inventoryData = [
{ id: 101, name: 'ワイヤレスマウス', price: 3500, stock: 15 },
{ id: 102, name: 'メカニカルキーボード', price: 12000, stock: 2 },
{ id: 103, name: 'USB-Cハブ', price: 4500, stock: 0 },
{ id: 104, name: 'モニターアーム', price: 8000, stock: 8 }
];
// 出力先の要素を取得
const listContainer = document.getElementById('stock-list');
// 2. 配列をループ処理してDOMを生成
// forEachを使用して各商品データ(item)にアクセスする
inventoryData.forEach((item) => {
// 在庫数に応じたステータス判定
let statusHTML = '';
if (item.stock === 0) {
statusHTML = '<span class="stock-alert">在庫切れ</span>';
} else if (item.stock < 5) {
statusHTML = `<span class="stock-alert">残り${item.stock}個</span>`;
} else {
statusHTML = '<span class="stock-ok">在庫あり</span>';
}
// HTML文字列の組み立て
const rowHTML = `
<div class="item-row">
<span class="item-name">${item.name}</span>
<span class="item-status">${statusHTML}</span>
</div>
`;
// コンテナに追加(insertAdjacentHTMLはパフォーマンスが良い)
listContainer.insertAdjacentHTML('beforeend', rowHTML);
});
カスタムポイント
- DOM生成方法の変更:上記の例では
insertAdjacentHTMLを使用して文字列として追加していますが、セキュリティ(XSS対策)やイベントリスナーの登録が必要な場合は、document.createElementを使って要素オブジェクトとして構築し、appendChildする方法に変更してください。 - 引数の省略:コールバック関数の引数
indexやarrayは不要であれば省略可能です。上記の例でもitemだけを受け取っています。
注意点
- ループを途中停止(break)できない
forEachは開始すると最後の要素まで止まりません。for文のようにbreakで脱出したり、continueでスキップしたりすることはできません(returnすると、その回の処理だけが終了し、次の要素へ進みます=実質continueと同じ挙動)。条件によって途中で処理を打ち切りたい場合は、通常のfor...of文を使用してください。 - 非同期処理との相性コールバック関数に
asyncをつけても、forEach自体は非同期処理の完了を待機しません(awaitできません)。配列内の非同期処理を直列または並列で実行したい場合は、for...ofループかPromise.allとmapを使用する必要があります。 - 戻り値はない加工した新しい配列が欲しい場合は
forEachではなくmapを使用してください。forEachの戻り値は常にundefinedです。
応用
メソッドチェーンによるデータ抽出と出力
filter メソッドなどでデータを絞り込んだ結果に対し、そのまま forEach を繋げて出力処理を行うパターンは非常に強力です。
const numbers = [10, 25, 32, 47, 50, 63];
// 1. 偶数だけを抽出 (filter)
// 2. コンソールに出力 (forEach)
numbers
.filter(num => num % 2 === 0)
.forEach(num => {
console.log(`偶数検出: ${num}`);
});
// 出力:
// 偶数検出: 10
// 偶数検出: 32
// 偶数検出: 50
まとめ
forEach は、配列データの表示や集計など、各要素に対して「アクションを起こす」場合に最適なメソッドです。インデックス管理が不要で記述ミスが減るため、単純な反復処理では for 文よりも優先して使用します。ただし、途中でループを抜けたい場合や非同期処理を扱う場合は、他のループ構文を選択する柔軟性も必要です。
