javascriptの関数について
jsの高階関数とコールバック関数、そもそもの関数についての自分の考え方等その他気になる部分をピックアップして記述。LWCに合わせた記述のアウトプット用の内容です。
大前提の考え方として
・関数はまず処理をひとまとまりにしたもので、使い方としては関数の定義、関数の呼び出しを行い処理を流すというような形になります。
・引数と戻り値があり、値を返したり受け取ったりできる
// これは関数の定義の記述 これだけでは処理が流れない
function add(a, b) { // a,bは引数でこの処理を呼ぶときに値を受け取って処理を行う
return a + b; // returnで戻り値を返す命令、この結果を呼び出し元に渡す
}
// add(3, 5)この記述が関数の呼び出し
let result = add(3, 5); // returnでの戻り値をここで受け取る
console.log(result); // 出力: 8
・関数式 (変数に格納している関数の事を指す) の記述もよく使われる記述方法になります。
ただ関数定義と違って「変数に関数を代入する」仕組みなので、定義された後でないと呼び出せません。
・無名関数を使う目的としては、他の場所で何度も呼び出す必要性が無いので名前を付ける必要が無い為です。ただデバックの際に名前が無いのでデバック時に分かりにくいというデメリットはあります。
// 変数greetにfunction() { ... } の無名関数を格納している
const greet = function() {
console.log("こんにちは!");
};
コールバック関数と高階関数について
高階関数(こうかいかんすう)とは関数を引数に取ったり、関数を返す関数のことをいう。
コールバック関数は他の関数に渡されて、あとで呼び出される関数のことをいう。
具体的な例が下記内容となります。
// これが高階関数、hello()関数を引数として受け取っているから
function doTwice(func) {
// doTwice の中で func という名前で hello が使えるようになる
func(); // hello();
func(); // hello(); となる
}
// 定義はただの関数
// ただ「他の関数に渡されて、後で呼ばれる」使われ方をするときに、コールバック関数と呼ばれる
function hello() {
console.log("こんにちは!");
}
doTwice(hello);
// 出力結果:
// こんにちは!
// こんにちは!
// setTimeoutが高階関数
// () => { ... }がコールバック関数(無名関数でもある)
setTimeout(() => {
console.log("1秒後に表示されます");
}, 1000);
よく使われる高階関数一覧
| 名前 | 高階関数 | コールバックの役割 |
|---|---|---|
forEach |
各要素に処理を行う | 各要素をどう処理するか |
map |
各要素を変換して新しい配列を作る | 変換の内容を定義する |
filter |
条件に合う要素を残す | 残すかどうかを決める |
reduce |
すべての要素を1つにまとめる | どう集計するかを定義する |
sort |
並び順を決める | 並び替えのルールを定義する |
// forEach
[1, 2, 3].forEach(num => console.log(num));
// map
const doubled = [1, 2, 3].map(num => num * 2);
console.log(doubled); // [2, 4, 6]
// filter
const even = [1, 2, 3, 4, 5].filter(num => num % 2 === 0);
console.log(even); // [2, 4]
// reduce
// accがこれまでの蓄積値、currは今見ている要素
// 0は合計の初期値
const sum = [1, 2, 3, 4].reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 10
// sort
// 今回の場合、(5, 2)を5 - 2 = 3 正(>0) bを先に(2,5)
// 続いて(2, 8)を2 - 8 = -6 負(<0) aを先に(2,8)のように並べ替えが続く処理
const sorted = [5, 2, 8, 1].sort((a, b) => a - b);
console.log(sorted); // [1, 2, 5, 8]
関数を返す関数
この記述も高階関数です。
function createMultiplier(x) {
// この中で新しい関数を作って返している
return function(y) {
return x * y;
};
}
const double = createMultiplier(2); // ←function(y) {return 2 * y;}; これが入ってる
const triple = createMultiplier(3); // ←function(y) {return 3 * y;}; これが入ってる
console.log(double(5)); // 10が出力 ←(2 * 5)←function(5) {return 2 * 5;};
console.log(triple(5)); // 15が出力 ←(3 * 5)←function(5) {return 3 * 5;};
【補足】
上記記述の仕組みは「クロージャ(closure)」という仕組みと関係している
返された関数(function(y) {return x * y;};)が、外の変数 x (function createMultiplier(x)この記述のxと記述している引数の事)を覚えている。
→ これを「クロージャ」と呼びます。
「返された関数が外のスコープの値(x)を覚えている」という点がポイントです。