多くのプログラミング言語は、処理の汎用性を高めるために、コールバックという仕組みを取り入れています。
JavaScriptでも、柔軟な処理を行うためにコールバック関数が使われています。
今回は、コールバック関数とは何か、例をもとに解説していきます。

コールバック関数

JavaScriptでは関数はオブジェクトの一つであり、関数を他の関数の引数として渡すことができます。
コールバック関数は、ある関数を呼び出す際に、その関数の引数に指定される別の関数のことです。
また、コールバック関数を受け取ったり返したりする関数のことを高階関数と呼びます。

function 高階関数(コールバック関数) {
  コールバック関数();
}

少し複雑に聞こえるかもしれませんが、整理すると次のような仕組みになっています。

  1. 関数は値であり、オブジェクト型の一つ
  2. 関数は値を受け取ることができる
  3. 関数に関数を渡すことができる
  4. 関数に渡される関数はコールバック関数
  5. コールバック関数を使う関数は高階関数

以下で詳しく使い方を解説するので、ここではイメージできていれば問題ありません。

コールバック関数の使い方

ここからは、コールバック関数の使い方を見ていきましょう。

関数を別々に定義する

まずは、2つの関数を別々に定義し、その内の1つを呼び出す際にもう片方の関数を引数として指定するパターンを見ていきます。

関数A(関数B);

次のコードには、高階関数のfuncAとコールバック関数のfuncBがあります。

// 高階関数 → funcBを引数に受け取れる
function funcA(text) {
  text(); // funcBの処理
  console.log('メッセージを受け取りました'); // funcAの処理
}

// コールバック関数 → funcAの呼び出し時に引数に指定される
function funcB() {
  console.log('こんにちは');
}

// funcAの呼び出し → 引数にfuncBを指定
funcA(funcB);

// "こんにちは"
// "メッセージを受け取りました"

funcAの呼び出し時に、引数にfuncBを指定しています。
そして、funcAの中では、textという引数で扱われています。
text()により、funcB内に記述した処理が行われます。

上記は関数宣言が使われていますが、関数式やアロー関数でもコールバック関数を使用することができます。

引数に直接関数を記述する

毎回関数を定義し、その関数をコールバック関数として渡すのは手間がかかります。
そういった場合に、コールバック関数を引数の中に直接記述することができます。

関数(関数の定義);

次のコードを見てください。
コールバック関数となる関数を引数の中にその場で定義します。

function funcA(text) {
  text();
  console.log('メッセージを受け取りました');
}

// funcAの呼び出し → 引数に関数式を定義
funcA(function() { 
  console.log('こんにちは');
});

// "こんにちは"
// "メッセージを受け取りました"

funcA(...)の呼び出しの中で、関数が定義されています。function(){...}がコールバック関数です。
処理内容が少ない場合、引数に直接関数を記述することで、2つの関数を別々に定義するよりも記述が少なくなります。

また、コールバックの多くの場面では、関数宣言と合わせて関数式やアロー関数が活用されるため、使えるようになると便利です。
アロー関数を使った場合、次のように書くことができます。

const funcA = (text) => {
  text();
  console.log('メッセージを受け取りました');
};

// funcAの呼び出し → 引数にアロー関数を定義
funcA(() => {
  console.log('こんにちは');
});

// "こんにちは"
// "メッセージを受け取りました"

コールバック関数が使われる場面

コールバック関数は、setTimeout関数を使った処理で良く使われます。
setTimeout関数は、JavaScriptに組み込まれている関数で、一定時間後に特定の処理を行います。一言で言うとタイマーのような機能です。

setTimeout関数の第一引数に関数、第二引数にミリ秒単位で秒数を指定します。

setTimeout(関数, 秒数);

実際のコードを見てみましょう。

function sayHi() {
  console.log('こんにちは');
}

setTimeout(sayHi, 3000); // 3秒後に出力

// "こんにちは"

実行してみると3秒後に'こんにちは'と出力されるはずです。

また、関数式を使うとこのように書くことができます。

setTimeout(function() {
  console.log('こんにちは');
}, 3000); 

// "こんにちは"

同様に、3秒後に'こんにちは'と出力されます。

コールバック関数は、非同期処理においても利用されます。
非同期処理は応用的な内容になるため、ここでは詳しい説明は省略しますが、以下の記事で解説しているので、気になる方はチェックしてみてください。

まとめ

今回は、コールバック関数について解説しました。

// ポイント
* コールバック関数は、引数として渡される関数のこと
* 高階関数は、コールバック関数を引数として使う関数のこと
* 関数A(関数B)や関数(関数の定義)のように使用できる
* setTimeoutや非同期処理で利用される

コールバック関数の書き方は人によっても異なるため、さまざまな関数定義の方法で使えるように身に付けていきましょう。

合わせて読みたい関数入門シリーズ

第1回:関数と宣言
第2回:関数と引数
第3回:関数と戻り値
第4回:関数式
第5回:関数オブジェクト
第6回:argumentsオブジェクト
第7回:アロー関数
第8回:コールバック関数(当記事)
第9回:関数とメソッド