カテゴリ: JavaScript 更新日: 2026/05/16

JavaScriptのクロージャー完全ガイド!初心者でもわかるクロージャーの基本と使い方

JavaScriptのクロージャーを作る基本的な書き方まとめ
JavaScriptのクロージャーを作る基本的な書き方まとめ

先生と生徒の会話形式で理解しよう

生徒

「先生、JavaScriptでクロージャーってよく聞くんですけど、そもそもクロージャーって何ですか?」

先生

「クロージャーとは、関数とその関数が作られたときの周りの環境(変数や関数)をセットにしたものです。簡単に言うと、関数の中で作られた変数を外からも使えるようにする仕組みです。」

生徒

「えっと、それって普通の関数とどう違うんですか?」

先生

「普通の関数は呼び出した時にだけ値を使えますが、クロージャーを使うと、その関数が作られたときの環境を覚えていて、後からでもその変数にアクセスできるんです。」

生徒

「なるほど!じゃあ、実際にどうやって書けばいいんですか?」

先生

「それでは、基本的な書き方を順番に見ていきましょう!」

1. クロージャーの基本構造とは?

1. クロージャーの基本構造とは?
1. クロージャーの基本構造とは?

クロージャーは、関数の中で関数を作り、内側の関数が外側の関数の変数を覚えている状態です。これにより、外側の関数が終了しても、内側の関数はその変数にアクセスできます。


function outer() {
  let count = 0;
  function inner() {
    count++;
    console.log(count);
  }
  return inner;
}
const counter = outer();
counter(); // 1
counter(); // 2
counter(); // 3

この例では、inner関数がouter関数のcountを覚えていて、呼び出すたびに値が増えています。

2. クロージャーで変数を隠す(プライベート変数)

2. クロージャーで変数を隠す(プライベート変数)
2. クロージャーで変数を隠す(プライベート変数)

クロージャーを使うと、外部から直接アクセスできない変数を作ることができます。これをプライベート変数と言います。


function createSecret() {
  let secret = "秘密の言葉";
  return function() {
    return secret;
  };
}
const getSecret = createSecret();
console.log(getSecret()); // 秘密の言葉

外からsecretに直接アクセスできないので、安全に値を管理できます。

3. クロージャーを使ったカウンターの応用例

3. クロージャーを使ったカウンターの応用例
3. クロージャーを使ったカウンターの応用例

クロージャーはカウンターを作るときにも便利です。関数ごとに独立したカウントを保持できます。


function makeCounter() {
  let num = 0;
  return {
    increment: function() { num++; return num; },
    decrement: function() { num--; return num; }
  };
}
const counter1 = makeCounter();
console.log(counter1.increment()); // 1
console.log(counter1.increment()); // 2
console.log(counter1.decrement()); // 1

この例では、incrementdecrementnumを覚えているので、外部から直接変更されません。

4. クロージャーで関数を返すパターン

4. クロージャーで関数を返すパターン
4. クロージャーで関数を返すパターン

クロージャーは関数を返すときによく使われます。返された関数は生成時の変数を覚えています。


function multiplier(factor) {
  return function(x) {
    return x * factor;
  };
}
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15

この例では、doubleは2倍、tripleは3倍を覚えているクロージャーになっています。

5. クロージャーとループの注意点

5. クロージャーとループの注意点
5. クロージャーとループの注意点

ループで関数を作る場合、クロージャーを正しく使わないと予期せぬ結果になることがあります。


for (var i = 1; i <= 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 100);
}
// 予想: 1 2 3
// 実際: 4 4 4

この場合、varは関数スコープなので、全ての関数が最後の値を覚えています。letを使うと解決できます。


for (let i = 1; i <= 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 100);
}
// 出力: 1 2 3

6. クロージャーを使ったイベントハンドラの例

6. クロージャーを使ったイベントハンドラの例
6. クロージャーを使ったイベントハンドラの例

クロージャーはイベントハンドラやコールバック関数でも使われます。クリックしたボタンごとに異なるメッセージを表示する例です。


function createButtonHandler(msg) {
  return function() {
    console.log("クリックされました: " + msg);
  };
}
const button1Handler = createButtonHandler("ボタン1");
const button2Handler = createButtonHandler("ボタン2");
button1Handler(); // クリックされました: ボタン1
button2Handler(); // クリックされました: ボタン2

このように、クロージャーを使うと関数ごとに異なるデータを保持して操作することができます。

7. クロージャーを理解するポイント

7. クロージャーを理解するポイント
7. クロージャーを理解するポイント

クロージャーを理解するには、「関数が作られた時点の環境を覚えている」という考え方が重要です。外側の関数が終了しても、内側の関数はその変数にアクセスできます。これにより、データの隠蔽や状態管理が簡単になります。

8. クロージャーのまとめ的な理解

8. クロージャーのまとめ的な理解
8. クロージャーのまとめ的な理解

JavaScriptのクロージャーは、変数を隠す、関数ごとに状態を保持する、ループやイベントハンドラでの予期せぬ動作を防ぐなど、初心者でも便利に使える機能です。ポイントは、関数の中で作られた関数が外側の変数を覚えているということです。コードを書きながら少しずつ慣れていくと、自然にクロージャーを活用できるようになります。

まとめ

まとめ
まとめ

本記事では、JavaScriptのクロージャーについて基礎から応用まで幅広く解説しました。クロージャーは関数とその関数が作られたときのスコープや変数の環境を保持する仕組みであり、外側の関数が終了した後も内側の関数がその変数にアクセスできる特徴があります。この性質を活かすことで、プライベート変数を作ったり、カウンターのような状態管理を行ったり、関数を返すパターンやイベントハンドラでの個別管理などが可能になります。

クロージャーの基本構造を理解することは、JavaScriptでのモジュール化やデータ隠蔽、状態保持などの応用にもつながります。例えば、カウンターや乗算関数のように関数ごとに独立したデータを持たせることができ、複数の機能を同時に実装しても互いに干渉しない設計が可能になります。また、ループで関数を生成する場合にvarを使うとすべての関数が最後の値を参照してしまう問題や、letを使うことで各関数が独立した値を覚える解決策も学びました。

クロージャーを活用することで、イベントハンドラやコールバック関数の処理も柔軟に設計できます。ボタンごとに異なる動作を保持したり、クリックイベントで個別のメッセージを表示することが可能です。このように、クロージャーは関数の設計やデータ管理を効率的に行うための強力なツールです。初心者でも基本パターンを理解し、少しずつ実践で使っていくことで、より複雑なJavaScriptアプリケーションでも自然に状態管理やデータ隠蔽を実現できるようになります。

さらに、クロージャーの理解には「関数が作られた時点の環境を覚えている」という考え方が欠かせません。この概念を意識することで、プログラムの挙動を予測しやすくなり、デバッグや保守性の高いコードを書くことにつながります。クロージャーを使った関数返却やイベント処理の設計も、同じ原則に基づいています。

サンプルプログラムで振り返る


function createCounter(initial) {
  let count = initial || 0;
  return {
    increment: function() { count++; return count; },
    decrement: function() { count--; return count; },
    getCount: function() { return count; }
  };
}
const counterA = createCounter(5);
console.log(counterA.increment()); // 6
console.log(counterA.getCount()); // 6
const counterB = createCounter();
console.log(counterB.increment()); // 1

このサンプルでは、counterAcounterBが独立した状態を保持しています。クロージャーを利用することで、それぞれのカウンターが他方の影響を受けずに動作することが確認できます。

先生と生徒の振り返り会話

生徒

「先生、クロージャーって結局何が便利なんですか?」

先生

「クロージャーを使うと、関数が作られたときの変数や環境を保持できるので、データを隠したり、状態を関数ごとに管理したりできるんだよ。普通の関数ではできないことも、クロージャーなら簡単に実現できるんだ。」

生徒

「なるほど、例えばカウンターを作るときに便利ってことですか?」

先生

「そうそう。関数を返すパターンでも使えるし、イベントハンドラごとに異なる処理を保持することもできるよ。ポイントは関数が作られた時点の環境を覚えているということだね。」

生徒

「ちょっと難しいけど、コードを書きながら理解していくと自然に使えるようになるんですね。」

先生

「その通り。最初はサンプルを動かして確認してみるといいよ。カウンターやイベント処理のように、小さな応用から始めるとクロージャーの仕組みが理解しやすいはずだ。」

生徒

「ありがとうございました、先生。これでクロージャーの基本と使い方が少しずつわかってきました!」

カテゴリの一覧へ
新着記事
New1
TypeScript
TypeScriptの関数に型をつける方法(引数・戻り値)を初心者向けに徹底解説!
New2
TypeScript
TypeScriptの始め方:開発環境の構築手順【初心者向け】
New3
TypeScript
TypeScriptでExpressのミドルウェアを型安全に定義する方法!バックエンド開発の初心者向け解説
New4
JavaScript
JavaScriptのfilterメソッドで条件に合う要素を抽出する方法
人気記事
No.1
Java&Spring記事人気No1
JavaScript
JavaScriptでフォームの値を取得する方法を徹底解説!valueプロパティの使い道
No.2
Java&Spring記事人気No2
JavaScript
JavaScriptでHTML5バリデーションAPIを使いこなす!初心者でもわかるフォーム入力チェック
No.3
Java&Spring記事人気No3
TypeScript
TypeScript学習におすすめの無料教材・リファレンスサイト【初心者向け】
No.4
Java&Spring記事人気No4
TypeScript
TypeScriptでコメントを書く正しい書き方と使い分け【初心者向けにやさしく解説】
No.5
Java&Spring記事人気No5
JavaScript
JavaScriptのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.6
Java&Spring記事人気No6
JavaScript
JavaScriptで要素を削除する方法(removeChild, removeなど)
No.7
Java&Spring記事人気No7
JavaScript
JavaScriptでオブジェクト指向のカプセル化を学ぶ!初心者でもわかるクラスとプロパティの保護方法
No.8
Java&Spring記事人気No8
JavaScript
JavaScriptの配列操作でよくあるエラーとその解決法まとめ