高階関数とコールバック関数について

高階関数とコールバック関数について

おはようございます。

JavaScript の学習を進めていく中で、コールバック関数や高階関数と言うものが出てきたので、今回はそれらについてまとめていきたいと思います。

コールバック関数とは?

コールバック関数は他の関数に引数として渡される関数で、外側の関数で何らかの処理やアクションを実行します。 MDN Web Docs 用語集: ウェブ関連用語の定義

何やら難しそうな響きですが、簡単なコードを使ってどういったものなのか見ていきましょう。

以下のコードは、taskOne と taskTwo という関数を定義してコンソールログに文字列を出力させる簡単な処理です。

// taskOneを定義
function taskOne(callback) {
  console.log('task 1'); // task 1

  // 引数に渡ってきた関数が実行される
  callback(); // task 2
}

// これが他の関数に渡される関数(コールバック関数)
function taskTwo() {
  console.log('task 2');
}

// 引数に定義した関数を渡す
taskOne(taskTwo);

taskOne と言う関数を見てみると callback という引数が渡されているのが分かります。

function taskOne(callback){}

そして taskOne 関数の中で実行されています。

taskOne 関数に渡された taskTwo 関数が、MDN の定義にも書かれていた他の関数の引数として渡される関数のことで、コールバック関数と呼ばれるものです。

引数は callback という名前にしていますが他の名前でも問題ありません。

// 引数の名前を変更
function taskOne(cb) {
  console.log('task 1'); // task 1

  cb(); // task 2
}

function taskTwo() {
  console.log('task 2');
}

taskOne(taskTwo);

JavaScript では関数もオブジェクト(データ型の一種)として扱われる

JavaScript では関数は関数オブジェクトとして扱われます。なので、関数を変数に格納したり引数に渡したりすることができます。

ちなみにこの関数の実行ですが、定義した関数の横に**丸括弧 () をつけることで、関数を実行して下さいね〜**という命令になります。

丸括弧 () をつけなければ実行されずに、ただ関数というデータが渡ってきただけになります。 以下のコードをデベロッパーツールを開いてコンソールに貼り付けて実行してみて下さい。

function taskOne(callback) {
  console.log('task 1');

  // 渡ってきた関数を実行せずにコンソールログに出力してみる
  console.log(callback);
  /*
  // 定義した関数の内容が出力される
  ƒ taskTwo() {
    console.log("task 2");
  }
  */
}

function taskTwo() {
  console.log('task 2');
}

taskOne(taskTwo);

関数が実行されずに、定義した関数(taskTwo)の内容が表示されると思います。

引数に渡した時点で実行してみると?

先のコードでコールバック関数に丸括弧 () を付けてしまうと、その時点で実行されてしまいコールバック関数を渡した関数内で関数が渡ってきません。

function taskOne(callback) {
  console.log('task 1');

  callback(); // callback is not a function
}

function taskTwo() {
  console.log('task 2');
}

// 実行してみる
taskOne(taskTwo());

// コンソールには以下の順番で出力される
// task 2
// task 1
// callback is not a function

高階関数とは?

高階関数とは引数として関数を持ったり、戻り値が関数である関数のことです。

これも言葉だと分かりにくいので例を見ていきましょう。

// 関数を引数に持っている関数(高階関数)
function taskOne(callback) {
  console.log('task 1');

  callback(); // callback is not a function
}

// 関数の引数として渡される関数(コールバック関数)
function taskTwo() {
  console.log('task 2');
}

taskOne(taskTwo());

// 戻り値が関数である関数
const taskThree = function () {
  // 無名関数を返している
  return function () {
    console.log('task 3');
  };
};

// 最初の実行で console.log の出力を定義した無名関数が返って来ている
taskThree(); // ƒ () { console.log("task 3") }

// 返ってきている無名関数も実行すると console.log の出力が見れる
taskThree()(); // task 3

// さらに別の関数式を定義して実行する方法もある
const myFunc = taskThree();

myFunc(); // task 3

関数を引数に持っている関数に関してはコールバック関数でみた例とコードは同じです。

このコールバック関数を受け取っている関数が高階関数ということになります。

もう一つの戻り値が関数である関数ですが、こちらはクロージャーという仕組みで頻出してきます。

まとめ

ここまでコールバック関数と高階関数の例を見てきました。

  • コールバック関数とは、他の関数に引数として渡される関数のこと
  • 高階関数とは、引数として関数をもったり、関数を実行した際に戻り値として関数を返したりする関数のこと

言葉だと理解するのが難しいですが、サンプルのコードを自分でいじってみて色んなパターンを試すと理解がしやすいと思います。