JavaScript 高階関数を説明するよ

なんとなく使っていた高階関数を言語化してみました。

##高階関数とは
高階関数を一言で表すと、**「関数を引数、戻り値として扱う関数」**のことです。

これにはJavaScriptの関数はデータ型の一種という前提があります。
JavaScriptでは関数そのものを他の数値型や文字列型などと同様に関数の引数として渡したり、戻り値として返したりすることができるのです。つまり関数を引数で扱うのが高階関数になります。

...言葉だけでは分かりにくいですね。


実際に高階関数をつかったコードを書いてみます。

```script.js
//高階関数higherOrderFunctionsを定義する
function higherOrderFunctions(data,f){
 for(var key in data){
  f(data[key],key);
 }
}

//ユーザー定義関数(高階関数の引数となる関数)を定義する
function userFunction(value ,key){
 console.log(key + ':' + value);
}

//実行
var array = [5,6,7,8,9,10 ];
higherOrderFunctions(array,userFunction);//0:5 1:6  2:7  3:8  4:9  5:10
//第一引数に処理する配列
//第二引数に配列を処理するユーザー定義関数(高階関数の引数となる関数)
```
*Higher-order Functionsというのは高階関数の英語

順を追って説明します。

はじめに、高階関数を定義しています。
`f`の部分に高階関数の**引数となる関数**が設定されています。
この高階関数はfor...in文によって`data`(配列)の個々の要素をひとつひとつ関数fに渡す処理になっています。

次に、高階関数の引数となる関数、ユーザー定義関数を定義します。
ここではひとつ上の関数（高階関数）から渡された`value` ,`key`を処理するコードが書かれています。

最後に高階関数の引数に処理する配列と使用する関数を設定することで結果が出力されます。


かんたんにまとめると下記の流れになります。
1. 高階関数のfor...in文で配列のキーと値を引数である関数`f`に渡す(渡す担当)
2. `f`に指定されたユーザー定義関数でキーと値をリストの形式に処理して出力する（処理担当）

*上記のユーザー定義関数はコールバック関数とも呼ばれます。
あとで呼び出される（コールバックされる）べき処理、という意味の関数です。

高階関数ではユーザー定義関数を自由に置き換えることができます。
例では配列の内容をリスト形式で表示しましたが、`f`に設定する関数を配列内の数値を合計する処理に変更することもできるのです。（高階関数は渡し方を担当するだけだからですね）

以上が基本的な高階関数の説明になります。


##代表的な高階関数　
代表的な高階関数の例としてArrayオブジェクトの**forEach, map, filter, sort, reduce**といったメソッドがあります。


###forEach
`array.forEach(callback[,that])`
　`array`: 配列
　`callback`: 配列の個々の要素を**処理**するための関数
　`that`: `callback`の中で`this`が示すオブジェクト

```script.js
var data = [5,6,7,8];
data.forEach(function(value,index,array){
  console.log(value * value);//25 , 36, 49, 64
});
```
`forEach`は、**配列の要素を順番に取り出してcallback関数に渡す**高階関数。
第一引数は要素の値
第二引数はインデックス番号
第三引数は元の配列
が指定される。第二、第三引数を利用しない場合は省略可。

###map
`array.map(callback[,that])`
　`array`: 配列
　`callback`: 配列の個々の要素を**加工**するための関数
　`that`: `callback`の中で`this`が示すオブジェクト

```script.js
var data = [5,6,7,8];
var result = data.map(function(value,index,array){
  return value * value;
});
console.log(result);;//[25, 36, 49, 64]
```
`map`は、**配列の要素を順番に取り出してcallback関数に渡し,戻り値として加工した結果を返す**高階関数。
（callback関数への値の渡し方は`forEach`と一緒。返し方が違う）

`map`は`forEach`と比較するとわかりやすいですね。
`forEach`はcallback関数で処理をするのでそのまま`console.log`で出力していますが、
`map`は戻り値として加工した結果を新しく返すので、別に`console.log`で出力しています。出力結果が`[25, 36, 49, 64]`と配列であることに注目してください。


###filter
`array.filter(callback[,that])`
　`array`: 配列
　`callback`: 配列の個々の要素を**判定**するための関数
　`that`: `callback`の中で`this`が示すオブジェクト

```script.js
var data = [5,6,7,8];
var result = data.filter(function(value,index,array){
  return value <= 6;
});
console.log(result);//[5, 6]
```
`filter`は、**指定されたcallback関数で個々の要素を判定し、条件に合致した要素だけを取り出す**高階関数。
callback関数（この場合、`value <= 6`）が`true`を返した値だけ、配列に書き戻すのが`filter`の役割。


###sort
`array.sort(callback[,that])`
　`array`: 配列
　`callback`: 配列の要素を**並び替える**ための関数
　`that`: `callback`の中で`this`が示すオブジェクト

```script.js
var data = [5,8,7,6];
var result = data.sort(function(a,b){
  return a - b;//昇順
});
console.log(result);[5, 6, 7, 8]

var result = data.sort(function(a,b){
  return  b - a;//降順
});
console.log(result);[8, 7, 6, 5]
```

`sort`は**デフォルトで配列を文字列として辞書順に並び替える**高階関数。
引数の設定を変えることで並べ方を変えることができます。
・引数は２つ（比較する配列要素）
・第一引数が第二引数より小さい場合は負数、大きい場合は正数を返す


###reduce
`array.reduce(callback[,init])`
　`array`: 配列
　`callback`: 配列の要素を**左から右へ処理する**ための関数
　`init`: 初期値

```js
var data = [5,6,7,8];
var result = data.reduce(function(a,b){
  return a + b;
});
console.log(result);//26
```
`reduce`は、**隣同士の２つの要素を左から右へcallback関数で処理してひとつの値にする**ための高階関数。

上記の場合、要素の左から順に
5+6で11
11+7で18
18+8で26 
26が返ってくる。

右から左へ処理したい場合は**reduceRight**という高階関数が用意されている。


他にもArrayオブジェクトには**every, some, find, findIndex**といったメソッドが用意されています。

##まとめ
高階関数は**「関数を引数、戻り値として扱う関数」**のこと。
高階関数はcallback関数への要素の渡し方を担当
callback関数が処理方法を担当

ありがとうございました。