高階関数の基本 [JavaScript]


JavaScriptにおける高階関数とは？
高階関数はさまざまなプログラミング言語で使用することができ、
主に２つの役割があります。

高階関数の役割。

:::note info
１、引数として関数を受け取る、関数
２、戻り値に関数を指定する、関数
:::

また、一般的に高階関数はプログラムの柔軟性と簡潔性を向上させるために利用されます。

関数を受け取る関数？関数を指定する関数？
とは一体なんなのでしょうか？

１つずつわかりやすく噛み砕いて説明していきます。



## 目次：
- [高階関数 「関数を引数として受け取る」](#高階関数-関数を引数として受け取る)
- [高階関数 「戻り値に関数を指定する」](#高階関数-戻り値に関数を指定する)


## 高階関数 「関数を引数として受け取る」

関数は、値なので、変数に入れることができます。

#### 例： 変数に関数式を代入

```js
let greet = function() {
    console.log("Hello");
}

greet()
```

こちらの例では、greetという変数の中に、関数式を代入しています。
そして、greet()という変数を呼び出すと、中に入っていた関数の内容を呼び出すことができます。

```text:出力結果：
Hello
```

このように、変数に入れることができるということは、
**関数の引数**として渡すことができます。

#### 例：関数を引数として受け取る関数

関数を引数として受け取る関数を作ってみます。

今回は、callTwiceという関数を２回実行する関数に、
console.logで（"Hello"）と出力する関数を渡します。


引数として受け取る関数は、以下のように定義され、実行されます。

:::note info
高階関数：「関数を引数として受け取る」　 
・関数を定義し、関数を呼び出す。例では、callTwice関数を定義する。
・callTwice関数の中で、引数にfunc関数を渡されることを期待している。
・func()関数を呼び出す。
:::
#### 関数の内容：
*callTwice 関数：渡された関数を２回出力する関数*

```js
function callTwice(func) {
    func();
    func();
}
```
・callTwice関数の引数として、パラメータ(func)と入れる。
（このfuncには、関数が定義されていることを期待している。下記の例のgreetのような関数式)
・func();　callTwice関数を実行する。



#### 引数として渡される側の関数を定義する。

関数の内容： 
*greet 関数：console.logで"Hello"と出力する関数*

```js
function greet() {
    console.log("Hello");
}

callTwice(greet)

```

作成したgreet関数をcallTwiceに渡す。**callTwice(greet)**

注意：渡すのは、**greet関数**。 
greet()と()丸括弧をつけて渡してしまうと、実行されたものを渡してしまう。
今回の場合は何も返してないので、実行するとundefinedが返ってしまう。 

:::note info
高階関数 「関数を引数として受け取る」　
作成手順まとめ：

２つの関数を作る

１：関数を引数として受け取る関数。
・１−１：関数を定義
・１−２：定義した関数のパラメータに受け取る関数を設定（例では、func）
・１−３：関数を実行（例では、func）
    
２：関数を渡す側の関数を作成
・２−１：関数を定義
・２−２：関数を関数に渡す
渡される側の関数「callTwice」渡す側の関数「greet」
:::

## 高階関数 「戻り値に関数を指定する」

関数から関数を返す例：

ある数字が特定の範囲に入っているかを確認する関数を
作成してくれる関数を作ってみたいと思います。

複雑でしてよくわかりずらいですね・・・

#### 例：特定の範囲に、指定した数字があるかをtrueかflseで返す関数。

まずは、
指定した数字が、特定の範囲内にあるかを確認する関数を作成します。

isBetweenという関数を作成。
numというパラメータに値が渡され、その値が50以上かつ、100以下であるかを確認できる関数です。

```js
function isBetween(num) {
    return num >= 50 && num <= 100;
}

isBetween(70)

isBetween(150)
```

```text:出力結果：
true

false
```

では、指定した数字が、
別の値の範囲内にあるかどうかを確認したい場合はどうでしょう？

類似の関数で別の値を取る関数を作成する必要があります。

#### 例２：特定の範囲に、指定した数字があるかをtrueかflseで返す関数２回目。
isBetween2という関数を作成。
numというパラメータに値が渡され、その値が1以上かつ、10以下であるかを確認できる関数です。


```js
function isBetween2(num) {
    return num >= 1 && num <= 10;
}

isBetween(5)

isBetween(20)
```

```text:出力結果：
true

false
```


このように、特定の値を知りたい度、類似の関数を作成するのは非常に非効率です。

そんな時に、高階関数の関数から関数を返す例が活用できます。

:::note info
高階関数：「戻り値に関数を指定する」
・関数を定義し、関数を呼び出す。例では、makeBetweenFunc関数を定義する。
・makeBetweenFunc関数の中で、パラメータの値を設定する。
・引数として受け取った値(num)が、特定の範囲内にあるかどうかを確認する関数を返す。
・作成された関数を別の値（変数）に格納し、再利用することも可能。
:::

こちらの例では、
makeBetweenFuncという関数に、minとmaxというパラメータを受け取るように設定。

受けとった値を使い、
内部の関数でminとmaxの値が、numと比べて特定の範囲内にあるかどうかを確認する関数を返しています。

また、作成された関数を別の変数に入れ、再利用することも可能です。

```js
function makeBetweenFunc(min,max) {
    return function(num) {
        return num >= min && num <= max;
    }
}

isChild = makeBetweenFunc(0,18);
```
#### 例：３、高階関数を使い、isChildという新たな関数を作成。

作成した高階関数を使って、0以上18未満の数字をisChildという変数に格納。
作成した関数isChildを使い、入力した数字が指定範囲内かどうかを判定する関数を作成できた。

```js
const isChild(15)

const isChild(30)

```

```text:出力結果：
true

false
```
作成した高階関数は、複製も簡単にすることができます。

#### 例：４高階関数を使い、isAdult、isSeniorという新たな関数を複製。

作成した高階関数を使って、19以上64未満の数字をisAdultという変数に格納。
作成した関数isAdultを使い、入力した数字が指定範囲内かどうかを判定する関数を作成できた。

同じく、65以上120未満の数字でisSeniorという関数も作成。


isAdult、isSeniorの例のように、高階関数を作ると、同じことをするが、別の入力値で試したいことを複製する場合に簡単に対応することができます。

```js
function makeBetweenFunc(min,max) {
    return function(num) {
        return num >= min && num <= max;
    }
}

isAdult = makeBetweenFunc(19,64);

isSenior = makeBetweenFunc(65,120);

```

```js

const isAdult(20)

const isAdult(5)

const isSenior(70)

const isSenior(40)

````
```text:出力結果：
true

false

true

false
```


::: note info
高階関数 「関数から関数を返す例」　
作成手順まとめ：

２つの関数を作る

１：関数を作成。
・１−１：関数を定義
・１−２：定義した関数のパラメータに内部に送るパラメータを設定。
    
２：関数を返す関数
・２−１：関数を定義し、return(関数を返す)する。
・２−２：関数に渡す関数を作成する。
:::