配列のforEachメソッドを使ってみよう

学習の目標

本章では、以下の内容を学習します。

  • forEachメソッドの基本的な使い方を理解する
  • コールバック関数の概念を学ぶ
  • for文とforEachの違いと使い分けを習得する
  • インデックスの取得方法を理解する

はじめに

これまでの章では、配列の各要素に対して何らかの処理を行いたい場合、for文を使って一つずつ要素を取り出していました。JavaScriptには、配列の処理をもっと簡単に、そして読みやすく書くことができるforEachメソッドがあります。

forEachメソッドは、配列のすべての要素に対して、指定した処理を順番に実行してくれる便利な機能です。前回学んだアロー関数と組み合わせることで、非常に簡潔で分かりやすいコードを書くことができるようになります。

配列を扱うプログラムでは、forEachメソッドは頻繁に使われる機能の一つです。まずは基本的な使い方から、一緒に学んでいきましょう。

forEachメソッドの基本的な使い方

forEachメソッドは、配列のメソッドの一つです。配列の各要素に対して、指定した関数を実行してくれます。まずは簡単な例で、for文と比較しながら見てみましょう。

VS Codeで新しいHTMLファイルforeach-test.htmlを作成してください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>forEachメソッドのテスト</title>
</head>
<body>
    <h1>forEachメソッドのテスト</h1>
    
    <script>
        const fruits = ["りんご", "バナナ", "オレンジ"];
        
        console.log("=== for文を使った場合 ===");
        for (let i = 0; i < fruits.length; i++) {
            console.log(fruits[i]);
        }
        
        console.log("=== forEachを使った場合 ===");
        fruits.forEach(function(fruit) {
            console.log(fruit);
        });
    </script>
</body>
</html>

このHTMLファイルを保存してブラウザで開き、開発者ツールのConsoleを確認してください。以下のような表示が現れるはずです。

=== for文を使った場合 ===
りんご
バナナ
オレンジ
=== forEachを使った場合 ===
りんご
バナナ
オレンジ

どちらも同じ結果が表示されますが、コードの書き方が大きく異なることが分かります。forEachを使った方が、「配列の各要素に対して何かをする」という意図が明確に伝わります。

forEachメソッドの仕組み

forEachメソッドの基本的な構造を理解してみましょう。

配列.forEach(function(要素) {
    // 各要素に対して実行したい処理
});

forEachメソッドは、配列の要素を一つずつ取り出して、指定した関数に渡してくれます。上記の例では、fruits配列の各要素(「りんご」「バナナ」「オレンジ」)が、順番にfruitという引数として関数に渡されています。

この時、forEachメソッドに渡している関数のことをコールバック関数と呼びます。コールバック関数とは、他の関数によって呼び出される関数のことです。forEachメソッドが、配列の各要素についてこのコールバック関数を呼び出してくれるのです。

アロー関数と組み合わせて使ってみよう

前回学んだアロー関数を使うことで、forEachメソッドをより簡潔に書くことができます。HTMLファイルに以下のコードを追加してみましょう。

<script>
    const numbers = [1, 2, 3, 4, 5];
    
    console.log("=== 通常の関数を使ったforEach ===");
    numbers.forEach(function(num) {
        console.log("数値: " + num);
    });
    
    console.log("=== アロー関数を使ったforEach ===");
    numbers.forEach((num) => {
        console.log("数値: " + num);
    });
    
    console.log("=== アロー関数の短縮記法 ===");
    numbers.forEach(num => console.log("数値: " + num));
</script>

このコードを実行すると、すべて同じ結果が表示されますが、書き方がどんどん簡潔になっていることが分かります。

=== 通常の関数を使ったforEach ===
数値: 1
数値: 2
数値: 3
数値: 4
数値: 5
=== アロー関数を使ったforEach ===
数値: 1
数値: 2
数値: 3
数値: 4
数値: 5
=== アロー関数の短縮記法 ===
数値: 1
数値: 2
数値: 3
数値: 4
数値: 5

特に最後の短縮記法では、処理が1行なのでとても読みやすくなっています。ただし、複数行の処理を行う場合は、波括弧を使った通常の書き方を使います。

コールバック関数の概念を理解しよう

forEachメソッドを理解するために、コールバック関数の概念について少し詳しく説明します。コールバック関数とは、「後で呼び出してもらう関数」のことです。

forEachメソッドの場合、私たちは「各要素に対して何をするか」という処理を関数として定義します。そして、forEachメソッドが配列の要素を一つずつ取り出して、その都度私たちが定義した関数を呼び出してくれるのです。

<script>
    // コールバック関数を別途定義することもできる
    function printWithMessage(item) {
        console.log("項目: " + item);
    }
    
    const colors = ["赤", "青", "緑"];
    
    // 定義した関数をコールバックとして渡す
    colors.forEach(printWithMessage);
    
    // 直接関数を定義して渡すこともできる
    colors.forEach(function(color) {
        console.log("色: " + color);
    });
</script>

この例では、printWithMessageという関数を事前に定義して、それをforEachのコールバック関数として使用しています。このように、関数を変数のように扱って、他の関数に渡すことができるのがJavaScriptの特徴の一つです。

インデックスも取得してみよう

forEachメソッドでは、配列の要素だけでなく、そのインデックス(何番目の要素か)も取得することができます。コールバック関数の第2引数として、インデックスが渡されます。

<script>
    const subjects = ["国語", "数学", "英語"];
    
    console.log("=== インデックス付きで表示 ===");
    subjects.forEach((subject, index) => {
        console.log(index + "番目: " + subject);
    });
    
    // より実用的な例:順番を1から始める
    console.log("=== 1から始まる番号付き ===");
    subjects.forEach((subject, index) => {
        const number = index + 1;
        console.log(number + ". " + subject);
    });
</script>

このコードを実行すると、以下のような結果が表示されます。

=== インデックス付きで表示 ===
0番目: 国語
1番目: 数学
2番目: 英語
=== 1から始まる番号付き ===
1. 国語
2. 数学
3. 英語

配列のインデックスは0から始まるため、人間が読みやすい番号にしたい場合はindex + 1とします。このように、forEachメソッドを使うことで、要素の値とその位置の両方を簡単に取得できます。

for文とforEachの違いと使い分け

for文とforEachメソッドは、どちらも配列の各要素に対して処理を行うことができますが、それぞれに特徴があります。どちらを使うべきかを理解するために、違いを整理してみましょう。

書きやすさと読みやすさ

for文は、インデックスを使って配列の要素にアクセスするため、処理の意図が分かりにくい場合があります。一方、forEachメソッドは、「配列の各要素に対して処理を行う」という意図が明確です。

<script>
    const scores = [85, 92, 78, 90];
    
    console.log("=== for文:意図が分かりにくい ===");
    for (let i = 0; i < scores.length; i++) {
        if (scores[i] >= 80) {
            console.log("合格: " + scores[i] + "点");
        }
    }
    
    console.log("=== forEach:意図が明確 ===");
    scores.forEach(score => {
        if (score >= 80) {
            console.log("合格: " + score + "点");
        }
    });
</script>

forEachを使った方が、「各スコアについて、80点以上なら合格と表示する」という処理の流れが自然に読めます。

処理の制御について

for文では、breakcontinueを使って処理を制御することができますが、forEachメソッドでは基本的にすべての要素を処理します。途中で処理を止めたい場合は、for文の方が適しています。

<script>
    const testNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    console.log("=== for文:5を見つけたら処理を停止 ===");
    for (let i = 0; i < testNumbers.length; i++) {
        console.log("処理中: " + testNumbers[i]);
        if (testNumbers[i] === 5) {
            console.log("5を見つけました!処理を停止します");
            break;
        }
    }
    
    console.log("=== forEach:すべての要素を処理 ===");
    testNumbers.forEach(num => {
        console.log("処理中: " + num);
        if (num === 5) {
            console.log("5を見つけました!でも処理は続きます");
        }
    });
</script>

どちらを使うべきか

一般的には、以下のような基準で使い分けます。

  • 配列のすべての要素に対して同じ処理を行いたい場合:forEach
  • 途中で処理を停止したい場合:for文
  • 配列の要素を変更したり、新しい配列を作りたい場合:forEachや他の配列メソッド
  • 複雑なループ制御が必要な場合:for文

多くの場合、単純に「各要素に対して何かをする」という処理では、forEachメソッドの方が読みやすく、書きやすいコードになります。

より実践的な例で理解を深めよう

forEachメソッドの使い方を、もう少し実践的な例で学んでみましょう。

<script>
    // 学生の情報を管理する配列
    const students = [
        { name: "田中", score: 85, subject: "数学" },
        { name: "佐藤", score: 92, subject: "英語" },
        { name: "山田", score: 78, subject: "国語" },
        { name: "鈴木", score: 90, subject: "理科" }
    ];
    
    console.log("=== 学生の成績一覧 ===");
    students.forEach((student, index) => {
        const number = index + 1;
        console.log(number + ". " + student.name + "さん");
        console.log("   科目: " + student.subject);
        console.log("   点数: " + student.score + "点");
        
        // 点数に応じてコメントを追加
        if (student.score >= 90) {
            console.log("   評価: 優秀!");
        } else if (student.score >= 80) {
            console.log("   評価: 良好");
        } else {
            console.log("   評価: もう少し頑張りましょう");
        }
        console.log(""); // 空行を入れて見やすくする
    });
    
    // 合計点数を計算
    let totalScore = 0;
    students.forEach(student => {
        totalScore += student.score;
    });
    
    const averageScore = totalScore / students.length;
    console.log("=== 統計情報 ===");
    console.log("総学生数: " + students.length + "人");
    console.log("合計点数: " + totalScore + "点");
    console.log("平均点数: " + averageScore + "点");
</script>

このコードは、学生の成績データを管理して、一覧表示と統計計算を行っています。forEachメソッドを使うことで、複雑なデータ構造でも読みやすく処理できることが分かります。

forEachメソッドの注意点

forEachメソッドを使う際の注意点もいくつかあります。

戻り値がない

forEachメソッドは、処理を実行するだけで、新しい配列や値を返しません。計算結果を取得したい場合は、外部の変数を使うか、後で学ぶ他のメソッド(mapfilterなど)を使います。

<script>
    const prices = [100, 200, 300];
    
    // forEach は戻り値がない
    const result1 = prices.forEach(price => price * 1.1);
    console.log("forEachの戻り値: " + result1); // undefined
    
    // 計算結果を取得したい場合は外部変数を使う
    const taxIncludedPrices = [];
    prices.forEach(price => {
        taxIncludedPrices.push(price * 1.1);
    });
    console.log("税込価格: " + taxIncludedPrices);
</script>

元の配列は変更されない

forEachメソッド自体は元の配列を変更しません。ただし、コールバック関数の中で配列の要素を直接変更することは可能です。

<script>
    const originalNumbers = [1, 2, 3];
    
    // forEachは元の配列を変更しない
    originalNumbers.forEach(num => num * 2);
    console.log("forEach後の配列: " + originalNumbers); // [1, 2, 3]のまま
    
    // 配列の要素を直接変更することは可能
    const mutableNumbers = [1, 2, 3];
    mutableNumbers.forEach((num, index, array) => {
        array[index] = num * 2;
    });
    console.log("直接変更後の配列: " + mutableNumbers); // [2, 4, 6]
</script>

まとめ

本章では、JavaScriptの配列forEachメソッドについて学びました。以下の内容を理解できたことと思います。

  • forEachメソッドは配列のすべての要素に対して指定した処理を実行する
  • コールバック関数の概念と、関数を他の関数に渡すという考え方
  • アロー関数と組み合わせることで簡潔なコードが書ける
  • インデックスも同時に取得できること
  • for文との違いと適切な使い分けの方法
  • forEachメソッドの注意点と制限

forEachメソッドは、配列を扱うプログラムでとてもよく使われる機能です。「配列の各要素に対して何かをする」という処理が必要になったら、forEachメソッドを思い出してください。次回は、配列を変換したり絞り込んだりできるmapfilterメソッドについて学んでいきます。

このセクションは有料サブスクリプションへの登録、またはログインが必要です。完全なコンテンツにアクセスするには、料金ページ(/pricing)をご覧ください。購入済みの場合は、ログインしてください。

Starterプランでより詳しく学習

この先のコンテンツを読むにはStarterプラン以上が必要です。より詳細な解説、実践的なサンプルコード、演習問題にアクセスして学習を深めましょう。

作成者:とまだ
Previous
アロー関数の書き方を覚えよう