はじめに
配列のメソッドであるforEach, map, filterがよくわからない!っていう人は、もしかしたらアロー関数とコールバック関数の理解があやふやなのかもしれません(私はそうでした。。)
この記事では、まず従来の関数の書き方を復習してから、アロー関数とコールバック関数について説明します。
その後、forEach, map, filterについて説明していきます。
従来の関数の復習
まず、(アロー関数でない)従来の関数の書き方を復習しておきます。
関数宣言
関数はこのように宣言します。
function fn() {
// 関数が呼び出された時の処理
}
関数式
数値や文字列等と同じように、関数自体も変数に代入できます。
関数を変数に代入している式を関数式と言います。
const fn = function() {
// 関数が呼び出された時の処理
}
この変数に代入された関数式は名前を持たない1ため、無名関数と呼ばれます。
アロー関数
アロー関数はES2015から導入された関数式の記述方法です。
名前の通り矢印 => を使って無名関数を定義します。
const arrowFn = () => {
// 関数が呼び出された時の処理
}
()で引数を受け取り、{}内で処理を行います。
具体例を見ていきましょう。
const doubleFn = (num) => {
return num * 2;
}
console.log(doubleFn(1)); // 2
引数をnumで受け取り、num * 2を実行して結果を返しています。
省略記法
アロー関数は、条件を満たせば省略して書くことができます。
| 条件 | 省略できるところ |
|---|---|
| 引数が1つ |
()は省略可 |
{}内で処理される関数式が1つ |
{}とreturnが省略可(関数式の結果が返り値になる) |
上の例のアロー関数は条件を両方とも満たすので、以下のように省略して書けます。
const doubleFn = num => num * 2;
コールバック関数
コールバック関数は、引数として関数に渡される関数のことです。
コールバック関数はES2015から導入されたわけではなく、従来の関数でも使用できます。
従来の関数
function sayHello() {
console.log("Hello");
}
function greet(callback) {
callback(); // "Hello"
}
greet(sayHello);
sayHello関数がコールバック関数です。greet関数の引数として渡されています。
そして、sayHello関数は、callback()として実行され、Helloが表示されてます。
無名関数
コールバック関数に名前をつけず、無名関数を引数として直接渡すこともできます。
// sayHello関数を作らない
function greet(callback) {
callback();
}
greet(function() {
console.log("Hello");
})
sayHello関数は作らず、直接greet関数に無名関数を渡しています。
アロー関数
そして、コールバック関数をアロー関数で書くと以下のようになります。
greet(() => {
console.log("Hello");
})
ここまで理解できれば、forEachメソッドなども理解しやすくなると思います。
forEach
さて、いよいよ本題のforEachメソッドの説明に入りましょう。
forEachは、配列の要素1つ1つに対して、与えられたコールバック関数を実行するメソッドです。
const numbers = [1, 2, 3];
numbers.forEach((num) => {
console.log(num); // 1 2 3
});
配列numbersの要素が順番にコールバック関数の引数numに渡され、console.log(num);が実行されます。
| numbersの要素 | num | 実行される関数式 |
|---|---|---|
| 0番目 | 1 | console.log(1); |
| 1番目 | 2 | console.log(2); |
| 2番目 | 3 | console.log(3); |
省略記法
条件を満たしていればコールバック関数を省略して書けます。
numbers.forEach(num => console.log(num));
map
mapメソッドは、配列の要素1つ1つに対して、与えられたコールバック関数を実行し、実行結果を新しい配列として返します。
const numbers = [1, 2, 3];
const newNumbers = numbers.map((num) => {
return num * 2;
});
console.log(newNumbers); // (3) [2, 4, 6]
配列numbersの要素が順番にコールバック関数の引数numに渡され、num * 2を実行します。
forEachと異なるのは、実行結果を新しい配列として返す点です。
返ってきた配列をnewNumbersという変数に格納しています。
省略記法
条件を満たしていればコールバック関数を省略して書けます。
const newNumbers = numbers.map(num => num * 2);
filter
filterメソッドは、配列の要素1つ1つに対して、与えられたコールバック関数を実行し、条件を満たす要素だけを新しい配列として返します。
const evenNumbers = numbers.filter((num) => {
return num % 2 === 0;
});
console.log(evenNumbers); // (2) [2, 4]
配列numbersの要素が順番にコールバック関数の引数numに渡され、num % 2 === 0を実行します。
mapと異なるのは、実行結果がtrueの場合だけ新しい配列として返す点です。
返ってきた配列をevenNumbersという変数に格納しています。
省略記法
条件を満たしていればコールバック関数を省略して書けます。
const evenNumbers = numbers.filter(num => num % 2 === 0);
おまけ : reduceメソッドについて
同じく配列のメソッドであるreduceについては別途記事にまとめましたので、以下をご参照ください。
参考資料
-
fnは変数の名前であり、代入された関数式自体には名前がついていません ↩