目次
概要
ES6以降、forEach や for...of といった便利なループ構文が登場しましたが、伝統的な for 文が不要になったわけではありません。
「インデックス(添字)を数値として自由に操作できる」という点は、他の構文にはない強力なメリットです。本記事では、「1つ飛ばしで処理する」「前後の要素と比較する」「逆順に処理する」といった高度な制御が必要な場面での for 文の活用法を解説します。
仕様(入出力)
for 文の基本構文
for (初期化式; 条件式; 増減式) {
// 繰り返す処理
}
| パート | 説明 |
| 初期化式 | ループ開始時に1度だけ実行されます。通常はカウンタ変数の宣言(let i = 0)を行います。 |
| 条件式 | 各ループの開始前に評価されます。true の間だけ処理が続行されます(例: i < array.length)。 |
| 増減式 | 各ループの終了後に実行されます。カウンタ変数を更新します(例: i++)。 |
- 入力: 配列データ
- 出力: 配列要素へのアクセス結果、または計算結果
基本の使い方
インデックスを使った標準的なループ
配列の要素にアクセスするには 配列[i] の形式を使用します。
const steps = ['Step1', 'Step2', 'Step3'];
// i は 0, 1, 2 と変化する
for (let i = 0; i < steps.length; i++) {
console.log(`現在の工程: ${steps[i]} (index: ${i})`);
}
コード全文(HTML / JavaScript)
ここでは、週間売上データを分析し、「前日との売上差」を計算してレポート出力するシステムを作成します。
「前の要素(i - 1)」を参照する必要があるため、forEach よりもインデックス制御が容易な for 文が最適です。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sales Analysis Report</title>
<style>
.report-card {
font-family: 'Helvetica Neue', Arial, sans-serif;
border: 1px solid #ddd;
padding: 20px;
width: 350px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.report-title {
margin-top: 0;
color: #333;
border-bottom: 2px solid #007bff;
padding-bottom: 5px;
}
.data-row {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.diff-plus { color: green; font-weight: bold; }
.diff-minus { color: red; font-weight: bold; }
.diff-even { color: gray; }
</style>
</head>
<body>
<div id="sales-report" class="report-card">
<h3 class="report-title">週間売上推移レポート</h3>
<div id="report-content">
</div>
</div>
<script src="analysis.js"></script>
</body>
</html>
JavaScript
/**
* 売上データ解析スクリプト
* for文を使って「前日比」を算出する
*/
// 1. 売上データ(単位: 千円)
const dailySales = [120, 145, 130, 130, 160, 210, 190];
const days = ['月', '火', '水', '木', '金', '土', '日'];
// 出力先
const reportContainer = document.getElementById('report-content');
/**
* 差分に応じたHTMLスパン要素を生成するヘルパー関数
*/
const createDiffHtml = (diff) => {
if (diff > 0) return `<span class="diff-plus">▲ ${diff}</span>`;
if (diff < 0) return `<span class="diff-minus">▼ ${Math.abs(diff)}</span>`;
return `<span class="diff-even">± 0</span>`;
};
// 2. 解析ロジック
// 初日は比較対象(前日)がないため、i = 1 (2日目) からスタートできるのがfor文の強み
for (let i = 0; i < dailySales.length; i++) {
const currentSales = dailySales[i];
const currentDay = days[i];
let diffInfo = '-';
// 2日目以降(i >= 1)の場合のみ前日比較を行う
if (i > 0) {
const prevSales = dailySales[i - 1]; // 前日のデータを取得
const diff = currentSales - prevSales;
diffInfo = createDiffHtml(diff);
} else {
diffInfo = '<span style="font-size:0.8em; color:#999;">(基準日)</span>';
}
// HTMLの組み立て
const rowHtml = `
<div class="data-row">
<span>${currentDay}曜日: ¥${currentSales},000</span>
<span>${diffInfo}</span>
</div>
`;
reportContainer.insertAdjacentHTML('beforeend', rowHtml);
}
カスタムポイント
- 開始位置の調整:コード例では条件分岐
if (i > 0)を使っていますが、初期化式をlet i = 1に変更すれば、最初から2つ目の要素(インデックス1)から処理を開始でき、コードをさらに短縮できます。 - ステップ数の変更:増減式を
i += 2に変更すれば、1つ飛ばしで要素を取得できます(例:偶数日のデータだけ抽出したい場合など)。
注意点
- 範囲外アクセス(Off-by-one error)条件式を
i <= array.lengthと書いてしまうミスが頻発します。配列の最後のインデックスはlength - 1なので、=を付けると存在しない要素にアクセスしてしまいundefinedになります。必ずi < array.lengthと記述してください。 - 無限ループ条件式が永遠に
trueになる設定(例:iを減らす処理を書くべきところで増やしてしまう等)をするとブラウザがフリーズします。増減式のロジックは慎重に確認しましょう。
応用
逆順ループ(後ろから前に処理する)
最新のデータ(配列の末尾)から過去に遡って処理したい場合は、for 文が唯一の選択肢となります。
const history = ['Page1', 'Page2', 'Page3'];
// length - 1 (最後の要素) から開始し、0 まで減らしていく
for (let i = history.length - 1; i >= 0; i--) {
console.log(`履歴: ${history[i]}`);
}
// 出力: Page3 -> Page2 -> Page1
まとめ
for 文は記述量が多くなりがちですが、インデックス(i)という強力な武器を使えるため、以下のような場面では forEach や for...of よりも適しています。
- 前後の要素と比較したい場合(
array[i]とarray[i-1]) - 処理を途中から始めたい場合(
let i = 5) - 逆順に処理したい場合(
i--)
配列操作の基本にして奥義とも言える構文ですので、必ずマスターしておきましょう。
