クロージャ
上級読み方:クロージャ|英語:Closure
関数が定義されたスコープの変数を記憶し続ける仕組みで、データの隠蔽に使えるよ。いつ使う? カウンターの値を外部から直接変更されたくないとき、関数に「状態」を持たせたいときに使うよ。間違いやすいポイント: ループ内でクロージャを使うと、全ての関数が同じ変数を参照してしまうことがあるよ。letを使えば解決するよ。
やさしい説明
クロージャは、関数が自分の外側の変数を「覚えている」仕組みです。関数の実行が終わっても、その変数にアクセスし続けられます。
「秘密の部屋」に例えると、関数が終わっても部屋の中の変数は消えず、返された内側の関数だけがその部屋に入れます。外からは直接アクセスできません。
カウンター、プライベート変数、関数ファクトリーなどに使われます。JavaScriptの重要な概念ですが、初心者のうちは「関数が外の変数を覚えている」と理解すればOKです。
具体例・使い方
// カウンター(外から直接変更できない)
function createCounter() {
let count = 0; // この変数を「覚えている」
return {
increment: () => ++count,
getCount: () => count
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.getCount(); // 2
// count に直接アクセスはできない(安全!) いつ使う?
プライベートな状態を持つ関数を作るとき、イベントリスナーで外側の変数を参照するとき、React の useState も内部的にクロージャを使っています。
間違いやすいポイント
❌ ループ内のクロージャで変数が共有される
// ❌ 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にしましょう。
関連用語
📖 関連レッスン
レッスンを見る →