目次
概要
ES2015 (ES6) で導入された for...of 文は、配列などの反復可能なオブジェクト(イテラブル)を処理するための最もモダンで読みやすい構文です。
従来の for 文のような煩雑なインデックス管理が不要で、かつ forEach メソッドでは不可能な「ループの途中脱出(break)」や「スキップ(continue)」、さらに「非同期処理の待機(await)」が可能という強力な特徴を持っています。本記事では、ログ解析処理を例にその柔軟な挙動を解説します。
仕様(入出力)
for...of 構文
for (const element of array) {
// 各要素に対する処理
}
| 構成要素 | 説明 |
| element | ループごとに現在の要素が代入される変数。通常は const で定義します。 |
| array | ループ対象となる配列(または文字列、Map、Setなどのイテラブル)。 |
- 特徴:
- break: ループを完全に終了します。
- continue: 現在の周回をスキップして次へ進みます。
- await:
async関数内で使用すれば、非同期処理を順番に実行できます。
基本の使い方
配列の値を順に取り出す
インデックス番号を気にする必要がなく、直感的に記述できます。
const scores = [80, 95, 72];
for (const score of scores) {
console.log(`点数: ${score}`);
}
// 出力:
// 点数: 80
// 点数: 95
// 点数: 72
コード全文(HTML / JavaScript)
サーバーから取得したシステムログを解析し、表示するデモです。
「特定の重大エラー(Critical)が見つかった時点で解析を即座に中止する(break)」 という、forEach では実装できない処理を行います。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log Analyzer</title>
<style>
.log-container {
font-family: 'Consolas', 'Monaco', monospace;
background-color: #1e1e1e;
color: #d4d4d4;
padding: 20px;
border-radius: 8px;
width: 400px;
}
.log-line {
margin: 5px 0;
padding: 5px;
border-left: 3px solid transparent;
}
.type-info { border-color: #4caf50; color: #a5d6a7; }
.type-warning { border-color: #ff9800; color: #ffe0b2; }
.type-critical { border-color: #f44336; color: #ffcdd2; background: #5a1010; }
.alert-box {
margin-top: 15px;
padding: 10px;
background-color: #ffeb3b;
color: #333;
font-weight: bold;
display: none; /* 初期状態は非表示 */
border-radius: 4px;
}
</style>
</head>
<body>
<div class="log-container">
<h3>System Log Analysis</h3>
<div id="log-output">
</div>
<div id="alert-message" class="alert-box">
⚠️ CRITICAL ERROR DETECTED! STOPPING...
</div>
</div>
<script src="log_analysis.js"></script>
</body>
</html>
JavaScript
/**
* ログ解析スクリプト
* Criticalエラー検出時にループを脱出(break)する例
*/
// 1. 解析対象のログデータ
const serverLogs = [
{ id: 1, type: 'Info', message: 'System boot sequence started.' },
{ id: 2, type: 'Info', message: 'Network services initialized.' },
{ id: 3, type: 'Warning', message: 'High CPU usage detected (85%).' },
{ id: 4, type: 'Critical', message: 'Database connection failed!' },
{ id: 5, type: 'Info', message: 'Retry connection...' }, // これは処理されないはず
{ id: 6, type: 'Info', message: 'System shutdown.' } // これも処理されないはず
];
// DOM要素の取得
const outputArea = document.getElementById('log-output');
const alertBox = document.getElementById('alert-message');
/**
* ログを表示し、致命的エラーがあれば停止する関数
*/
const analyzeLogs = (logs) => {
// for...of ループの開始
for (const log of logs) {
// ログの種類に応じたスタイルクラスを決定
const cssClass = `type-${log.type.toLowerCase()}`;
// HTML要素を作成して追加
const logElement = document.createElement('div');
logElement.className = `log-line ${cssClass}`;
logElement.textContent = `[${log.type}] ${log.message}`;
outputArea.appendChild(logElement);
// ★ ここがポイント
// "Critical" エラーだった場合、アラートを表示してループを強制終了する
if (log.type === 'Critical') {
console.warn('致命的なエラーを検知しました。解析を中断します。');
alertBox.style.display = 'block';
// break文を実行すると、このループから即座に脱出する
// 以降のログ(id:5, id:6)は処理されない
break;
}
}
};
// 実行
analyzeLogs(serverLogs);
カスタムポイント
- continueの活用:「Warning」だけは無視してログに出さない、といった場合は
if (log.type === 'Warning') { continue; }と記述すれば、その周回だけスキップして次のログ処理へ進めます。 - 変数のスコープ:ループ変数を
constではなくletで宣言すると、ループ内でその変数に再代入することが可能になります(通常は推奨されませんが、特殊な計算ロジックで使う場合があります)。
注意点
- インデックスが直接取れない
forEach((val, index) => ...)と異なり、for...ofは標準では現在のインデックス(何番目か)を提供しません。インデックスが必要な場合は、下記の「応用」で紹介するentries()を使うか、従来のforEachを検討してください。 - オブジェクトはループできない
const obj = { a: 1, b: 2 };に対してfor (const val of obj)を実行するとエラーになります。オブジェクトのプロパティを回したい場合はfor...in文かObject.values(obj)を使用してください。
応用
インデックスも同時に取得したい場合
array.entries() メソッドを使うと、[インデックス, 要素] のペアを取得できるため、分割代入と組み合わせて使用します。
const fruits = ['Apple', 'Banana', 'Orange'];
for (const [index, fruit] of fruits.entries()) {
console.log(`${index + 1}番目は ${fruit} です`);
}
// 出力:
// 1番目は Apple です
// 2番目は Banana です
// ...
まとめ
for...of 文は、現代のJavaScriptにおいて最も汎用的で強力なループ構文です。
- 可読性が高い:
ofという英単語の通り、直感的に読める。 - 制御が可能:
breakで停止、continueでスキップができる(forEachにはない機能)。 - 非同期対応:
for await...ofを使えば非同期処理も扱える。
全要素を単純に処理するだけなら forEach も便利ですが、条件によって処理を制御したい場合は for...of を第一選択肢としてください。
