JS memo

お洒落にJavaScript。

2019年5月13日21:08

JavaScriptのコールバックとは何か

メインビジュアル

JavaScriptのコールバックとは何か

今回はJavaScriptのコールバック(callback)について説明します。
コールバックと聞くと難しそうに感じますが、実際JavaScriptを 書いたことのある人なら知らず知らずのうちに利用していると思います。
コールバックはとても役に立つ機能なので一緒に理解していきましょう!

目次

  1. callbackの例
  2. callbackとは?
  3. callbackのメリット
  4. まとめ
  5. 参考動画

callbackの例

説明に入る前に、シンプルなcallbackの例を紹介します。

function x(){
  console.log("Taro");
}
function y(callback){
  console.log("hello");
  callback();
}
y(x);
// "hello"
// "Taro"

関数xを引数として関数yにパスして、y内でxが処理されています。
この時の関数xをコールバック関数、関数yを高階関数と言います。

callbackとは

callbackを理解するためにはざっくりとファーストクラスオブジェクト、コールバック関数、高階関数を理解しなければいけません。一つ一つを順に理解していきましょう。

まずファーストクラスオブジェクトとは何かということですが、結論から言うと、JavaScriptの関数はファーストクラスオブジェクトです。
ファーストクラスオブジェクトとは簡単に言うと自由に扱える数字や文字、配列(オブジェクト)などのデータのことです。 ファーストクラスオブジェクトには様々な特徴がありますが、今回知って欲しい特徴は、「関数に渡してその関数内で処理することができる値」ということです。

// ファーストクラスオブジェクト
let miso = "味噌";

// misoを引数として処理
function order(type){
  console.log(`${type}ラーメン`);
}
order(miso); //味噌ラーメン

JavaScriptでは数値や文字列、配列だけでなく関数を他の関数に渡して処理をすることができるので、「関数もファーストクラスオブジェクトとなることができる」と言うことです。

//ファーストクラスオブジェクト
function topping(){
  console.log("煮卵トッピングで");
}
// toppingを引数として処理
function order(callback){
  console.log("ラーメン");
  callback();
}
order(topping);
// "ラーメン"
// "煮卵トッピングで"

上記の例では関数toppingを関数orderに渡して呼び出されています。
この時のtoppingをコールバック関数、orderを高階関数と言います。

ファーストクラスオブジェクト → 自由に処理できる値で関数で引数とし呼び出せる

コールバック関数 → 他の関数で呼び出される関数

高階関数 → 他の関数を呼び出すための関数

JavaScriptでコールバックを利用するということはある関数を引数として他の関数で呼び出して処理することです。

コールバックの例で言えば、setTimeoutやwindow.addEventListenerなどはcallbackを利用しています。
このようにコールバックは身近で利用されているので、JavaScriptのコードを書いたことをある人なら知らず知らずのうちにcallbackを使用している可能性が高いです。

// callbackの例
window.addEventListener('load', () => {
  // 好きなコード
});

setTimeout(function(){
  // 好きなコード
},2000)

$(element).click(fucntion(){
  // 好きなコード
})

callbackのメリット

callbackのメリットの一つは非同期でも順番にコードを実行できると言うことです。
例えば、コールバックを利用しているjqueryのclick()は、指定した要素がclickされた後に関数を処理してくれます。
setTimeoutも指定された時間が経過したのちに関数を実行できる仕組みになっています。

他のメリットとしてはコードの追加や変更が簡単にすることができます。

例として2つの数値と計算方法を入力すると、入力値を元に計算した値が返ってくるcallbackを利用しないライブラリーを作成するとします。

function calc(num1, num2, c){
  if(c === 'plus'){
    return num1 + num2;
  } else if (c === 'minus'){
    return num1 - num2;
  }
}
calc(1,2,"plus"); // 3;

もしこのライブラリーの使用者が任意の二つの値を掛け算したい場合、この関数に直接手を加えなければいけません。

上記の例をcallbackを利用してライブラリーを作成すると、掛け算をしたい場合にライブラリーの関数を更新しなくても、自分で関数を定義することで掛け算もできるようになります。

function plus(num1, num2){
  return num1 + num2;
}
function minus(num1, num2){
  return num1 - num2;
}
// 自分で新たに関数を定義
function times(num1, num2){
  return num1 * num2;
}
function calc(num1, num2, callback){
  callback();
}
calc(1,2,times); // 2;

まとめ

JavaScriptのコールバックとはある関数を他の関数内で呼び出し、処理することです。
コールバックを使用することにより、非同期処理の後に実行できたり、新たに関数を定義して既存の関数で実行することができます。
今回は説明していませんが、コールバック地獄などデメリットもあるので、コールバックを利用する際は適切かどうか一度考えて利用してください。

参考動画

今回参考にした動画です。