JavaScript | 基礎構文:関数 – コールバック関数の基礎

JavaScript JavaScript
スポンサーリンク

コールバック関数って何者?

コールバック関数は、
「あとで呼び出してもらうために“渡しておく関数”」 です。

ふつうは「関数を“呼び出す”側」と「呼び出される側」がはっきり分かれていますが、
コールバックでは「関数を“引数として渡す”」ことで、
「いつ・どんなタイミングで実行するか」を相手に任せます。

一言でいうと、
「関数を値として渡して、“終わったらこれやってね”と予約しておく仕組み」 です。


まずは超シンプルなコールバックの例から

「終わったら呼んでね」をコードにするとこうなる

「作業が終わったら教えてね」というイメージで考えてみます。

function doTask(callback) {
  console.log("タスクを実行中...");
  callback(); // 終わったタイミングで呼び出す
}

function afterTask() {
  console.log("タスクが終わりました!");
}

doTask(afterTask);
JavaScript

流れを言葉で追うと、

  1. afterTask という関数を定義
  2. doTask に「引数として」afterTask を渡す
  3. doTask の中で callback() として呼び出す
  4. そのタイミングで afterTask が実行される

ここが重要です。
コールバック関数とは「自分で呼ぶのではなく、“誰かに呼んでもらうために渡す関数”」 です。
doTask(afterTask) の時点では afterTask は「実行されていない」。
実際に実行されるのは、doTask の中で callback() と呼ばれた瞬間です。


無名関数をその場で渡すパターン

わざわざ名前をつけずに書くことも多い

さっきは afterTask に名前をつけましたが、
実務では「その場で関数式(またはアロー関数)を書いて渡す」ことが多いです。

function doTask(callback) {
  console.log("タスクを実行中...");
  callback();
}

doTask(function () {
  console.log("タスクが終わりました!(無名関数)");
});
JavaScript

アロー関数ならこう。

doTask(() => {
  console.log("タスクが終わりました!(アロー関数)");
});
JavaScript

ここで渡している function () { ... }() => { ... } が、
まさに「コールバック関数」です。

「終わったらこれやってね」という“処理そのもの”を、
その場で書いて渡しているイメージです。


コールバック関数が本領発揮するのは「非同期処理」

「いつ終わるか分からない」からこそ“終わったタイミングで呼ぶ”

例えば、1秒後に何かをしたいとき。

setTimeout(function () {
  console.log("1秒経ちました");
}, 1000);
JavaScript

setTimeout の第1引数がコールバック関数です。
「1秒後にこの関数を呼んでね」と予約しているわけです。

アロー関数で書くとこう。

setTimeout(() => {
  console.log("1秒経ちました");
}, 1000);
JavaScript

ここが重要です。
非同期処理(時間がかかる処理)では、「終わった瞬間に何をするか」を
コールバック関数として渡す、というパターンが基本になります。

例えば、サーバーからデータを取ってくる処理を、
昔ながらのコールバックスタイルで書くとこうなります。

function fetchData(callback) {
  setTimeout(() => {
    const data = { message: "サーバーからのデータ" };
    callback(data); // 取れたデータを渡して呼び出す
  }, 1000);
}

fetchData((result) => {
  console.log("受け取ったデータ:", result);
});
JavaScript

fetchData は「いつデータが取れるか分からない」。
だから「取れたらこの関数を呼んで、そのときに結果を渡してね」とする。
これがコールバックの典型パターンです。


コールバック関数の「引数」として結果を受け取る

「終わったら呼ぶ」だけじゃなく「結果も渡す」

さっきの fetchData をもう一度見ます。

function fetchData(callback) {
  setTimeout(() => {
    const data = { message: "サーバーからのデータ" };
    callback(data);
  }, 1000);
}

fetchData((result) => {
  console.log("受け取ったデータ:", result);
});
JavaScript

ここでのポイントは、

callback(data) として「結果 data を引数に渡している」
呼び出し側では (result) => { ... } として「その結果を受け取る」

という対応関係です。

つまり、
「非同期処理の結果を、コールバック関数の引数として渡す」
という形になっています。

これにより、

「いつ終わるか分からない処理」
「終わったらやりたい処理」
「その処理に渡したい結果」

をきれいに分離できます。


コールバック関数がよく使われる標準的な場面

配列メソッド(forEach, map, filter など)

配列メソッドは、コールバック関数の練習に最適です。

forEach の例:

const numbers = [1, 2, 3];

numbers.forEach((n) => {
  console.log("要素:", n);
});
JavaScript

ここで (n) => { ... } がコールバック関数です。
配列の各要素に対して、順番に呼び出されます。

map の例:

const numbers = [1, 2, 3];

const doubled = numbers.map((n) => {
  return n * 2;
});

console.log(doubled); // [2, 4, 6]
JavaScript

map は「各要素に対してコールバックを実行し、その戻り値を集めて新しい配列を作る」メソッドです。

ここが重要です。
配列メソッドは「配列が“いつ・どの順番で”コールバックを呼ぶかを決めてくれていて、
自分は“要素1つに対して何をするか”だけを書けばいい、という分業になっている。

これが「コールバックの世界観」です。


コールバック関数の“本質”を言語化しておく

「制御の流れを相手に渡す」

普通の関数呼び出しはこうです。

const result = doSomething();
use(result);
JavaScript

「doSomething を呼ぶ → 結果を受け取る → 自分で次の処理をする」
という“自分主導”の流れです。

コールバックを使うと、こうなります。

doSomethingAsync((result) => {
  use(result);
});
JavaScript

「doSomethingAsync に“終わったらやる処理”を渡す →
あとは doSomethingAsync が好きなタイミングでそれを呼ぶ」

つまり、
「いつ実行するかの主導権(制御の流れ)を、相手に渡している」
ということです。

ここがコールバックの本質です。
だからこそ、非同期処理やイベント処理と相性がいい。
「いつ起きるか分からないこと」に対して、
「起きたときにやること」をあらかじめ渡しておけるからです。


初心者が最初に意識しておきたいポイント

「関数を“実行せずに渡す”感覚をつかむ

よくあるつまずきがこれです。

doTask(afterTask()); // ← これは NG
JavaScript

こう書くと、afterTask はその場で実行されてしまい、
doTask には「戻り値」が渡されます(たいてい undefined)。

正しくはこうです。

doTask(afterTask); // 関数そのものを渡す
JavaScript

もしくは、

doTask(() => {
  console.log("終わったよ");
});
JavaScript

ここが重要です。
afterTask() は“実行”、afterTask は“関数そのもの”」
コールバックとして渡したいのは“関数そのもの”の方です。


まとめ:コールバック関数の基礎で本当に押さえてほしいこと

コールバック関数は、
「あとで呼び出してもらうために、引数として渡す関数」

特に大事なのは次の感覚です。

  • 「関数を値として渡す」= doSomething(callback)
  • 「渡された関数を呼ぶ」= callback()
  • 非同期処理では「終わったらこの関数を呼んで、そのとき結果を引数で渡してね」という形になる
  • 配列メソッド(forEach, map, filter)は、コールバックの超良い練習台

まずは、

function doTask(callback) {
  console.log("タスク中...");
  callback("完了しました");
}

doTask((message) => {
  console.log("コールバック:", message);
});
JavaScript

このくらいのコードを、自分の手で何度か書いてみてください。

「関数を渡す」「渡された関数を呼ぶ」
この2ステップが体に馴染んだ瞬間、
非同期処理・イベント処理・配列操作など、
JavaScript の“気持ちいい書き方”が一気に見えてきます。

タイトルとURLをコピーしました