
配列メソッド(forEach、filter、mapなど)を学んだ際に出てきた「関数を引数に渡す」という概念。これが「コールバック関数」です。
コールバック関数とは
コールバック関数は、引数に入っている関数のことです。
const numbers = [1, 2, 3];
numbers.forEach((num) => {
console.log(num);
});
この (num) => { console.log(num); } の部分が、コールバック関数です。
コールバック関数の仕組み
普通の関数を引数として渡す
コールバック関数は、まず普通の関数として定義しておき、それを引数として渡すこともできます。
// 関数を定義
const printNum = (num) => {
console.log(num);
};
const numbers = [1, 2, 3];
// 関数を引数として渡す
numbers.forEach(printNum);
// 1
// 2
// 3
forEach は、配列の各要素に対して printNum 関数を呼び出しています。
コールバック関数を呼び出すときは()をつける
関数を実行するときは、() をつけます。
const greet = () => {
console.log("こんにちは");
};
// 関数を呼び出す(実行する)
greet(); // こんにちは
コールバック関数を渡すときは()をつけない
関数を引数として渡すときは、() をつけません。
const greet = () => {
console.log("こんにちは");
};
const numbers = [1, 2, 3];
// ❌ ()をつけると、関数が実行されてしまう
numbers.forEach(greet()); // エラー
// ✅ ()をつけないと、関数自体を渡せる
numbers.forEach(greet);
重要: greet() は「関数を実行する」、greet は「関数自体を渡す」という違いがあります。
例:タイマー関数
const sayHello = () => {
console.log("こんにちは");
};
// ❌ ()をつけると即座に実行される
setTimeout(sayHello(), 1000); // すぐに「こんにちは」と表示される
// ✅ ()をつけないと1秒後に実行される
setTimeout(sayHello, 1000); // 1秒後に「こんにちは」と表示される
関数を直接引数の中で定義する
コールバック関数は、引数の中で直接定義することもできます。これが最も一般的な書き方です。
const numbers = [1, 2, 3];
// 関数を直接定義
numbers.forEach((num) => {
console.log(num * 2);
});
// 2
// 4
// 6
わざわざ関数名をつけて定義する必要がなく、コードがシンプルになります。
コールバック関数に引数を渡す
コールバック関数にも、普通の関数と同じように引数を渡すことができます。
const numbers = [1, 2, 3, 4, 5];
// コールバック関数の引数numに、配列の各要素が渡される
numbers.forEach((num) => {
console.log(`数値: ${num}`);
});
// 数値: 1
// 数値: 2
// 数値: 3
// 数値: 4
// 数値: 5
forEach は、配列の各要素を順番に num に代入してコールバック関数を実行します。
引数の数を合わせる
コールバック関数を定義するとき、引数の数を合わせる必要があります。
forEachの場合
forEach のコールバック関数は、最大3つの引数を受け取れます。
const fruits = ["りんご", "バナナ", "オレンジ"];
fruits.forEach((fruit, index, array) => {
console.log(`${index}: ${fruit}`);
console.log(`配列の長さ: ${array.length}`);
});
// 0: りんご
// 配列の長さ: 3
// 1: バナナ
// 配列の長さ: 3
// 2: オレンジ
// 配列の長さ: 3
引数の意味
- 第1引数:要素そのもの
- 第2引数:インデックス番号
- 第3引数:配列全体
必要な引数だけ使えばOKです。
// 要素だけ使う
fruits.forEach((fruit) => {
console.log(fruit);
});
// 要素とインデックスを使う
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
自作関数でコールバック関数を使う
自分で作った関数でも、コールバック関数を引数として受け取ることができます。
const repeat = (count, callback) => {
for (let i = 0; i < count; i++) {
callback(i); // コールバック関数を呼び出す
}
};
// 使い方
repeat(3, (num) => {
console.log(`${num}回目`);
});
// 0回目
// 1回目
// 2回目
callback(i) で、渡されたコールバック関数を実行しています。
実用例:処理の共通化
const processNumbers = (numbers, callback) => {
const results = [];
numbers.forEach((num) => {
results.push(callback(num));
});
return results;
};
const numbers = [1, 2, 3];
// 2倍にする
const doubled = processNumbers(numbers, (num) => num * 2);
console.log(doubled); // [2, 4, 6]
// 3倍にする
const tripled = processNumbers(numbers, (num) => num * 3);
console.log(tripled); // [3, 6, 9]
コールバック関数を使うことで、同じ処理の「やり方」だけを変えられます。
Pythonとの比較
Pythonにも似た概念があります。
# Python
def repeat(count, callback):
for i in range(count):
callback(i)
repeat(3, lambda i: print(f"{i}回目"))
// JavaScript
const repeat = (count, callback) => {
for (let i = 0; i < count; i++) {
callback(i);
}
};
repeat(3, (i) => {
console.log(`${i}回目`);
});
Pythonの lambda は、JavaScriptのアロー関数に相当します。
コールバック関数を使うメリット
1. コードの再利用性が高まる
const calculate = (a, b, operation) => {
return operation(a, b);
};
console.log(calculate(5, 3, (x, y) => x + y)); // 8(足し算)
console.log(calculate(5, 3, (x, y) => x * y)); // 15(掛け算)
2. 処理を柔軟に変えられる
const numbers = [1, 2, 3, 4, 5];
// 偶数だけ抽出
const evens = numbers.filter((num) => num % 2 === 0);
// 3より大きい数だけ抽出
const greaterThan3 = numbers.filter((num) => num > 3);
同じ filter メソッドでも、コールバック関数を変えることで異なる結果が得られます。
今日の学びのポイント
- コールバック関数: 引数に入っている関数
- 関数を呼び出すときは
()をつける - 関数を渡すときは
()をつけない - 関数を直接引数の中で定義することもできる
- コールバック関数にも引数を渡せる
- 引数の数を合わせる必要がある
- 自作関数でもコールバック関数を使える
コールバック関数は、JavaScriptの重要な概念です。配列メソッドやイベント処理など、様々な場面で使われます。

コメント