概要
JavaScriptにおけるクロージャ(Closure)は「関数の中から外部変数を参照できる機能」ではない。
それは**“一度生成された実行スコープを保持し、状態をカプセル化するための制御構造”**である。
クロージャは、状態を外部から隠し、持続的に保持し、再実行時にその文脈を記憶する力を持つ。
これにより、キャッシュ、イベント処理、イミュータブル設計、モジュールのような構造的抽象化が可能になる。
本稿では、クロージャの動作原理と状態保持戦略、および設計的にどのように活用するかを解説する。
1. クロージャとは「スコープの束縛」
function createCounter() {
let count = 0;
return function () {
return ++count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
- ✅
count
はcreateCounter()
が終わっても破棄されない - ✅ 返された関数がスコープを保持し続けるため
2. クロージャによる状態カプセル化(情報隠蔽)
function createUser(name) {
let secret = 'classified';
return {
getName() {
return name;
},
revealSecret() {
return secret;
}
};
}
- ✅ 外部から
secret
に直接アクセスできない - ✅ クロージャによってプライベートな状態を構築可能
3. イベントハンドラとクロージャの設計
function bindButton(index) {
return function () {
console.log(`Button ${index} clicked`);
};
}
for (let i = 0; i < 3; i++) {
const btn = document.createElement('button');
btn.textContent = `Button ${i}`;
btn.onclick = bindButton(i);
document.body.appendChild(btn);
}
- ✅ ループ内の
i
をクロージャでキャプチャ - ✅ イベントハンドラに動的コンテキストを渡す安全な方法
4. キャッシュとメモ化への応用
function memoize(fn) {
const cache = {};
return function (key) {
if (cache[key]) return cache[key];
const result = fn(key);
cache[key] = result;
return result;
};
}
- ✅ 関数の外部で副作用を持たせず、内部状態でキャッシュ制御
- ✅ 再実行時にクロージャで記憶された状態を活用
5. クロージャを使うべきパターン
- ✅ 状態を外部に漏らさず保持したいとき
- ✅ 関数単位で状態を切り出したいとき
- ✅ 再帰・メモ化・コールバックに文脈を渡したいとき
- ✅ イベントハンドラでループ変数を安全に参照したいとき
設計判断フロー
① 外部から隠したい状態があるか? → クロージャで保持する
② 関数実行後も値を保持して再利用したいか? → 状態を閉じ込める
③ 繰り返し呼び出しで副作用なく状態を更新したいか? → イミュータブルなクロージャへ
④ コールバックやイベントで現在の文脈を渡したいか? → クロージャを返す関数を設計
⑤ モジュール設計でprivate状態を実装したいか? → クロージャを基本単位に構築
よくあるミスと対策
❌ ループ内の変数が全て同じ値で参照される
→ ✅ クロージャでスコープを固定した関数を返す
❌ すべての状態をオブジェクトで管理して肥大化
→ ✅ 状態ごとに関数 + クロージャで責務を分離
❌ 状態の変更がグローバルに波及する
→ ✅ 外部からアクセスできないローカルスコープに閉じる
結語
クロージャとは「関数の中から外の変数が見える」ことではない。
それは**“スコープを封じ、状態を保持し、コードを制御可能な構造へと再構成するための設計手段”**である。
- 関数の外で定義された変数は、関数内から閉じ込めることで「生きた状態」となる
- 状態を明示的に外部に公開しないことで、セキュアかつ保守性の高い設計が可能になる
- クロージャは単なる技術ではなく、状態管理・抽象化・制御設計のための戦略的構造
JavaScriptにおけるクロージャ設計とは、
“責務を持つ状態をスコープに封じて制御する、ミニマルかつ強靭な設計戦略である。”