JS

クロージャ

上級

読み方:クロージャ|英語: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にしましょう。

関連用語

📖 関連レッスン

レッスンを見る →

関連ブログ記事

⚠️ 関連するエラー

❓ 関連するQ&A