[JavaScript]The New Standard for Array Loops Understanding for…of and Its Differences from forEach

目次

Overview

Introduced in ES2015 (ES6), the for…of statement is the most modern and readable syntax for processing iterable objects like arrays. Unlike traditional for loops, it eliminates the need for complex index management. More importantly, it provides powerful features that the forEach method lacks, such as the ability to stop a loop early with break, skip iterations with continue, and wait for asynchronous tasks with await. This article demonstrates these flexible behaviors using a system log analysis scenario.


Specifications (Input/Output)

  • Input: An array of system log objects (e.g., Error, Warning, Info).
  • Output: Logs rendered to the screen.
  • Operation: * Iterate through the logs and stop immediately if a “Critical” error is detected.
    • Use break to prevent further processing after a fatal error.

The for…of Syntax

for (const element of array) {
  // Logic for each element
}
ComponentDescription
elementA variable assigned the value of the current element in each iteration. Usually defined with const.
arrayThe array (or other iterable like String, Map, or Set) to be looped through.

Key Control Features

  • break: Terminates the loop completely.
  • continue: Skips the current iteration and moves to the next one.
  • await: When used inside an async function, it allows you to execute asynchronous operations in sequence.

Basic Usage

Extracting values from an array is intuitive because you do not have to manage index numbers.

const hardwareIds = [1024, 2048, 4096];

for (const id of hardwareIds) {
    console.log(`Device ID: ${id}`);
}

/*
Output:
Device ID: 1024
Device ID: 2048
Device ID: 4096
*/

Full Code (Log Analysis Scenario)

This demo analyzes system logs fetched from a server. It performs a task that is impossible with forEach: stopping the analysis immediately (break) as soon as a “Critical” error is found.

HTML

<!DOCTYPE html>
<html lang="en">
<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: 450px;
        }
        .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">
    <h2>System Log Analysis</h2>
    <div id="log-output">
        </div>
    <div id="alert-message" class="alert-box">
        ⚠️ CRITICAL ERROR DETECTED! ANALYSIS ABORTED.
    </div>
</div>

<script src="log_analysis.js"></script>
</body>
</html>

JavaScript

/**
 * Log Analysis Script
 * Example of breaking out of a loop when a Critical error is detected.
 */

// 1. Log data to be analyzed
const systemLogs = [
    { id: 1, type: 'Info', message: 'Mainframe communication established.' },
    { id: 2, type: 'Info', message: 'Security protocols active.' },
    { id: 3, type: 'Warning', message: 'Unusual traffic on port 80.' },
    { id: 4, type: 'Critical', message: 'Kernel panic detected in node-02!' },
    { id: 5, type: 'Info', message: 'Attempting automated recovery...' }, // This will not be processed
    { id: 6, type: 'Info', message: 'Cleanup task started.' }             // This will not be processed
];

const outputArea = document.getElementById('log-output');
const alertBox = document.getElementById('alert-message');

/**
 * Function to display logs and stop if a fatal error occurs
 */
const runLogAnalysis = (logs) => {
    // Start of the for...of loop
    for (const log of logs) {
        
        // Determine the CSS class based on log type
        const cssClass = `type-${log.type.toLowerCase()}`;
        
        // Create and append the log element
        const logElement = document.createElement('div');
        logElement.className = `log-line ${cssClass}`;
        logElement.textContent = `[${log.type}] ${log.message}`;
        outputArea.appendChild(logElement);

        // Key Logic:
        // If a "Critical" error is detected, show an alert and stop the loop.
        if (log.type === 'Critical') {
            console.warn('Fatal error detected. Aborting analysis.');
            alertBox.style.display = 'block';
            
            // The break statement exits the loop immediately.
            // Logs with id:5 and id:6 will be ignored.
            break;
        }
    }
};

// Execute the analysis
runLogAnalysis(systemLogs);

Customization Points

  • Using continue: If you want to ignore certain log types (e.g., skip “Warning” logs without stopping the loop), use if (log.type === 'Warning') { continue; }. This skips the current turn and moves to the next log.
  • Variable Scope: While const is standard for the loop variable, you can use let if you need to reassign the variable within the loop block for specific calculation logic.

Important Notes

  • Indices are not provided: Unlike forEach((val, index) => ...), for...of does not naturally provide the current index. If you need the position, you must use the entries() method as shown in the advanced section.
  • Objects are not iterable: Running for (const val of obj) on a plain object like {a: 1} will throw an error. To iterate through object properties, use for...in or Object.values(obj).

Advanced Applications

If you need to access both the value and the index, use the entries() method along with destructuring.

const services = ['Auth', 'Database', 'Cache'];

for (const [index, service] of services.entries()) {
    console.log(`Service #${index + 1}: ${service}`);
}

/*
Output:
Service #1: Auth
Service #2: Database
Service #3: Cache
*/

Summary

The for…of loop is the most versatile and powerful iteration syntax in modern JavaScript because it combines high readability with granular control. It allows developers to intuitively loop through arrays without managing indices while providing the essential capability to stop or skip iterations using break and continue. While forEach remains useful for simple operations on every element, for…of should be your first choice whenever you need to control the flow of the loop or handle asynchronous logic. Understanding these structural differences ensures that your data processing remains efficient and your code remains easy to maintain.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次