JS

クロージャ

上級

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

関連用語

  • スコープ — クロージャは外側のスコープの変数を参照し続ける
  • 関数 — クロージャは関数が関数を返すことで作られる
  • 変数 — クロージャが「覚えている」のは外側の変数

📖 関連レッスン

レッスンを見る →

関連ブログ記事

⚠️ 関連するエラー

❓ 関連するQ&A