クロージャ
上級読み方:クロージャ|英語:Closure
関数が定義されたスコープの変数を記憶し続ける仕組みで、データの隠蔽に使えるよ。
やさしい説明
クロージャは、関数が自分の外側の変数を「覚えている」仕組みです。関数の実行が終わっても、その変数にアクセスし続けられます。
「秘密の部屋」に例えると、関数が終わっても部屋の中の変数は消えず、返された内側の関数だけがその部屋に入れます。外からは直接アクセスできません。
カウンター、プライベート変数、関数ファクトリーなどに使われます。JavaScriptの重要な概念ですが、初心者のうちは「関数が外の変数を覚えている」と理解すればOKです。
具体例・使い方
// カウンター(外から直接変更できない)
function createCounter() {
let count = 0; // この変数をクロージャが「覚えている」
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count,
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.decrement(); // 1
counter.getCount(); // 1
// count に直接アクセスはできない(プライベートな状態!) クロージャが使われる実例
// 関数ファクトリー(設定を閉じ込めた関数を作る)
function createMultiplier(factor) {
return (num) => num * factor; // factor を覚えている
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
double(5); // 10
triple(5); // 15
// イベントリスナーで外側の変数を参照
function setupButton(message) {
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
console.log(message); // messageを覚えている
});
}
setupButton("クリックされました!"); React の useState も内部的にクロージャを使っています。const [count, setCount] = useState(0) の setCount は、コンポーネントの状態を「覚えている」クロージャです。
いつ使う?
- プライベートな状態を持つオブジェクトを作るとき(カウンター、モジュール)
- イベントリスナーで外側の変数を参照するとき
- 同じ設定を共有する複数の関数を作るとき(関数ファクトリー)
- React の useState / useCallback などの内部実装
間違いやすいポイント
❌ ループ内のクロージャで変数が共有される(var の罠)
var はブロックスコープを持たないため、ループ内のクロージャが同じ変数を参照してしまいます。let を使うとブロックごとに独立した変数になります。
// ❌ varだと全部同じiを参照してしまう
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 3, 3, 3
}
// ✅ letならブロックスコープで安全
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // 0, 1, 2
} よくある疑問
Q: クロージャの例は?
A: function counter() { let n = 0; return () => ++n; } const c = counter(); c(); // 1, c(); // 2。内側の関数がnを記憶し続けます。
Q: クロージャのメリットは?
A: 変数をプライベートにできます。外部から直接nを変更できないので、意図しない変更を防げます。
Q: クロージャでメモリリークは起きる?
A: 不要になったクロージャへの参照を保持し続けるとメモリリークの原因になります。不要になったら参照をnullにしましょう。
関連用語
📖 関連レッスン
レッスンを見る →