更新日:
【JavaScript】 forEachメソッドについて徹底解説!
forEachは、配列のすべての要素に対して、一つずつ順番に関数を実行するメソッドです。
1
2
3
配列.forEach(function(配列内の各要素) {
何らかの処理
});
forEachメソッドの基礎情報
この章では、forEach
メソッドの基礎情報について解説します。
forEachメソッドの基本的な使い方
forEach
メソッドは配列に対して使用されるメソッドです。forEach
メソッドを使うと、配列の各要素を順番に取り出し、その各要素に対して何らかの処理を実行するコールバック関数を引数として渡すことができます。その結果、要素の数だけコールバック関数が実行されます。
以下は基本的な使用方法です。
1
配列.forEach(コールバック関数);
わかりやすく書くと以下のようになります。
1
2
3
配列.forEach(function(配列内の各要素) {
何らかの処理
});
もしくは以下のようにも書くことができます。
1
配列.forEach(配列内の各要素 => 何らかの処理);
これだけではわかりにくいので基本的な例を見てみましょう。
1
2
3
4
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(number) {
console.log(number);
});
このコードでは、配列numbers
の各要素を順番に取り出し、それぞれをnumber
という変数に格納してから、console.log
によって出力します。出力結果は以下の通りです。
1
2
3
4
5
1
2
3
4
5
アロー関数を使うと、さらに簡潔に書くことができます。
1
2
3
4
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => {
console.log(number);
});
また、以下のような使い方もできます。
1
2
3
4
5
6
7
8
9
const users = [
{ name: '山田', age: 25 },
{ name: '中村', age: 30 },
{ name: '新井', age: 35 }
];
users.forEach(user => {
console.log(user.name);
});
この場合の出力結果は次のようになります。
1
2
3
山田
中村
新井
forEach
は繰り返し処理を行うだけなのでDOMの操作などの操作に向いています。
1
2
3
4
const elements = document.querySelectorAll('.my-class');
elements.forEach(element => {
element.style.color = 'blue';
});
この例では、クラス名がmy-class
の全てのDOM要素の文字色を青に変更します。
また、forEach
は単に繰り返し処理を行うだけであり、返り値を返さないため、常にundefined
を返します。
mapとの違い
forEach
と同じような繰り返し処理のメソッドにmap
メソッドがあります。map
メソッドも配列に対して使用し、各要素に何らかの処理を繰り返し実行するメソッドです。
違いとしてforEach
が返り値を返さないのに対し、map
は繰り返し処理後に新しい配列を作成します。
1
2
3
4
const numbers = [1, 2, 3, 4, 5];
const newArray = numbers.map(number => number + 1);
console.log(newArray); // [2, 3, 4, 5, 6]
この例では配列の要素を順番に取り出し、それに1を足した数が入った新たな配列が作成されます。
以下がforEach
とmap
との違いになります。
特徴 | forEach | map |
---|---|---|
戻り値 | undefined を返す |
新しい配列を生成して返す |
元の配列への影響 | 元の配列は変更されず、処理のみを行う | 元の配列は変更されず、新しい配列が生成される |
使用用途 | 各要素を反復処理するのに適している | 各要素を変換して新しい配列を生成するのに適している |
forEachメソッドの応用的な使い方
この章では、forEachメソッドの応用的な使い方について解説します。
オプションで使えるコールバック関数の引数
forEach
メソッドでは応用的な使い方をすることで、元の配列の中身を書き換えることができます。
実はコールバック関数の引数にはオプションとして2つの引数を使うことができます。
1
2
3
配列.forEach(function(各要素, インデックス, 使用した配列) {
繰り返す処理
});
使わない場合は省略します。
以下の例ではオプションとしてインデックスを引数として渡しています。
この例では、配列内の要素は3つあるため、indexにはそれぞれ0
、1
、2
が代入されます。
1
2
3
4
const numbers = [2,4,6]
numbers.map(function(number, index) {
console.log(index)
});
出力結果は以下のようになります。
1
2
3
0
1
2
forEach
メソッドでは、第3引数にforEach
を使用している配列、つまり元の配列が代入されます。そのため、以下のようにすると元の配列の中身を書き換えることができます。ただし、通常はmap
を使って新しい配列を作成する方が一般的です。
1
2
3
4
5
6
const numbers = [2,4,6]
numbers.foreach(function(number, index, array) {
array[index] = number + 1;
});
console.log(numbers) // [3, 5, 7]
forEachの第2引数
forEach
メソッドで第2引数として別のオブジェクトを指定することで、this
の参照先を変更することができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 人物のデータを表すオブジェクト
const peopleData = {
'田中': 25,
'山本': 30,
'菅原': 35,
'宮崎': 40
};
// 特定の人物を選択する
const selectedPeople = ['宮崎', '田中'];
// 選択された人物の年齢を取得する
selectedPeople.forEach(function(name) {
console.log(this[name]);
}, peopleData); // peopleDataがthisに置き換わる(forEachメソッドの第二引数に渡しているため)
出力結果は以下のようになります。
1
2
40
25
上の例ではforEach
メソッドのコールバック関数内でthis[name]
を使用して、指定された人物の年齢を取得しています。この場合のthis
はコールバック関数の第2引数で渡したpeopleData
のことを指します。name
の中にはselectedPeople
の要素が順番に入るので、peopleData
の配列から対応する人物の年齢を取得しています。
このようにthis
を使うことで、より柔軟なプログラミングが可能となります。this
について詳しく知りたい方はこちらの記事を参考にしてみてください。
使う際の注意点
この章ではforEach
メソッドを使う際の注意点を紹介します。
繰り返し処理からは抜けられない
forEach
メソッドのコールバック関数内ではbreak
が使えないため、繰り返し処理から抜け出すことができません。間違って記述しないようにしましょう。
1
2
3
4
5
6
7
8
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((num) => {
if (num === 3) {
break; // 構文エラーが発生する
}
console.log(num);
});
この場合以下のエラーが発生し、コードが止まります。
変更処理には向いていない
forEach
は繰り返し処理をするだけのメソッドで、元の配列には影響を与えません。以下のコードのように応用的な使い方で学んだやり方で元の配列の情報を変えることはできますが、map
など他のメソッドを使うことを検討した方が良いでしょう。
1
2
3
4
5
6
const numbers = [2,4,6]
numbers.foreach(function(number, index, array) {
array[index] = number + 1;
});
console.log(numbers) // [3, 5, 7]
できるだけ他の繰り返し処理のメソッドを使う
forEach
はただ単に繰り返し処理を実行するだけなので、何のために繰り返しを行なっているかが不明瞭です。そのためコードの可読性や保守性が低下し、バグが生じやすくなる可能性があります。できるだけmap、filter、reduceなどの他の繰り返し処理のメソッドを使うことを検討しましょう。
この記事のまとめ
- forEachメソッドは、配列に対して反復処理を行うために使用される
- 繰り返し処理を行うだけなので返り値はundefinedになる
- 同じようなメソッドにmapメソッドがある