カテゴリ: JavaScript 更新日: 2026/07/08

JavaScriptのクロージャーでイベントリスナーを簡単に実装する方法!初心者向け完全ガイド

JavaScriptのクロージャーを使ったイベントリスナーの実装例
JavaScriptのクロージャーを使ったイベントリスナーの実装例

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

生徒

「先生、JavaScriptでボタンをクリックしたときに特定の値を覚えて使う方法ってありますか?」

先生

「それはクロージャーを使うと簡単にできます。クロージャーとは、関数が自分の外側にある変数を覚えて使える仕組みです。」

生徒

「クロージャーを使うとどう便利になるんですか?」

先生

「例えば、複数のボタンを作ったときに、それぞれのボタンが自分専用の値を持ったままクリックされたときに正しく処理できます。」

生徒

「なるほど!具体的にはどうやって書くんですか?」

先生

「では、基本的なクロージャーを使ったイベントリスナーの例を見てみましょう。」

1. クロージャーとは何かを理解しよう

1. クロージャーとは何かを理解しよう
1. クロージャーとは何かを理解しよう

クロージャーとは、JavaScriptで関数の内部から外側の変数を覚えて使える仕組みです。簡単に言うと、関数が「メモ帳」を持っていて、外の情報を覚えて使えるようなイメージです。

クロージャーを理解することで、イベントリスナーやカウンター、非同期処理など、さまざまな場面で便利に使えます。

2. 基本的なクロージャーの作り方

2. 基本的なクロージャーの作り方
2. 基本的なクロージャーの作り方

まずはシンプルな例でクロージャーを確認してみましょう。下記は、関数を呼ぶたびに数をカウントする例です。


function createCounter() {
  let count = 0;
  return function() {
    count++;
    console.log("現在のカウント: " + count);
  }
}

const counter = createCounter();
counter(); // 現在のカウント: 1
counter(); // 現在のカウント: 2

この例では、内部関数が外側のcount変数を覚えているため、呼び出すたびに値が増えていきます。これがクロージャーの基本的な動作です。

3. クロージャーを使ったボタンイベントの基本

3. クロージャーを使ったボタンイベントの基本
3. クロージャーを使ったボタンイベントの基本

次に、ボタンをクリックしたときにメッセージを表示するイベントリスナーでクロージャーを使う例です。


const buttons = document.querySelectorAll(".btn");

for (let i = 0; i < buttons.length; i++) {
  (function(index) {
    buttons[index].addEventListener("click", function() {
      alert("ボタン番号: " + index);
    });
  })(i);
}

ここでは、即時関数(IIFE)を使ってindexをクロージャーとして覚えています。これにより、どのボタンをクリックしても正しい番号が表示されます。

4. クロージャーでクリックカウンターを作る

4. クロージャーでクリックカウンターを作る
4. クロージャーでクリックカウンターを作る

クロージャーを使えば、各ボタンに独立したクリックカウンターを持たせることも簡単です。


function createButtonCounter(button) {
  let count = 0;
  button.addEventListener("click", function() {
    count++;
    console.log(button.textContent + "のクリック回数: " + count);
  });
}

const btn1 = document.querySelector("#btn1");
const btn2 = document.querySelector("#btn2");

createButtonCounter(btn1);
createButtonCounter(btn2);

この例では、countがそれぞれのボタンごとに独立して覚えられるため、ボタンごとのクリック回数を正確にカウントできます。

5. クロージャーで複数イベントを管理する

5. クロージャーで複数イベントを管理する
5. クロージャーで複数イベントを管理する

クロージャーを使うと、複数のイベントで共通の処理や値を安全に管理できます。例えば、フォームの入力値を覚えておいて送信時にまとめて処理する場合などです。


function setupInputLogger(input) {
  let lastValue = "";
  input.addEventListener("input", function() {
    lastValue = input.value;
  });
  input.addEventListener("blur", function() {
    console.log("最後に入力された値: " + lastValue);
  });
}

const nameInput = document.querySelector("#name");
setupInputLogger(nameInput);

このようにクロージャーを使うと、イベントの種類が違っても同じ変数lastValueを覚えて使うことができます。

6. setTimeoutとクロージャーを組み合わせる

6. setTimeoutとクロージャーを組み合わせる
6. setTimeoutとクロージャーを組み合わせる

クロージャーは非同期処理でも大活躍します。例えば、ボタンをクリックした後に少し遅れてメッセージを表示する場合です。


function delayedAlert(button, message) {
  button.addEventListener("click", function() {
    setTimeout(function() {
      alert(message);
    }, 1000);
  });
}

const btnAlert = document.querySelector("#btnAlert");
delayedAlert(btnAlert, "クリックから1秒後に表示されました");

ここでもクロージャーがmessageを覚えているため、非同期でも正しい値が使われます。

7. クロージャーを使うときの注意点

7. クロージャーを使うときの注意点
7. クロージャーを使うときの注意点

クロージャーは便利ですが、使いすぎるとメモリを多く消費することがあります。また、古いブラウザでは挙動が異なる場合もありますので、必要な場面でだけ使うことが重要です。

また、クロージャーで変数を覚えすぎると、意図しない値が残ることがあります。常に必要な範囲で変数を管理しましょう。

8. クロージャーを活用してイベントリスナーを効率化しよう

8. クロージャーを活用してイベントリスナーを効率化しよう
8. クロージャーを活用してイベントリスナーを効率化しよう

クロージャーを使うことで、イベントリスナーの管理が簡単になり、同じ処理を複数の要素に安全に適用できます。例えば、ボタンごとのカウンター、入力値の記録、非同期処理など、多くの場面で活躍します。

初心者でもクロージャーの基本を理解すれば、JavaScriptでのイベント処理がより柔軟で効率的になります。ぜひ、今日紹介した例を自分で試して、クロージャーの感覚を掴んでみてください。

まとめ

まとめ
まとめ

今回の記事では、JavaScriptにおけるクロージャーの基本から、イベントリスナーとの組み合わせによる実践的な使い方までを丁寧に解説しました。クロージャーとは、関数が外側の変数や状態を覚えて保持できる仕組みであり、これを理解することで、ボタンごとの独立したクリックカウンターや入力フォームの値の追跡、非同期処理でのデータ保持など、さまざまな場面で便利に活用できます。特にイベントリスナーと組み合わせることで、DOM要素ごとの状態管理が簡単になり、複数のボタンやフォームを扱う際に、意図した挙動を確実に実現できます。

クロージャーを利用する際のポイントとしては、変数が関数内で保持され続けることを理解し、必要以上にメモリを消費しないように管理することが重要です。例えば、古いブラウザや大量の要素でクロージャーを多用する場合、不要な参照を残さないよう注意する必要があります。また、即時関数(IIFE)や関数生成パターンを活用することで、特定のスコープ内で変数を安全に管理でき、各要素の状態を独立して追跡できます。

さらに、クロージャーは非同期処理とも相性がよく、setTimeoutPromiseと組み合わせることで、クリックイベントやタイマー処理の中でも変数を正しく保持して使用することができます。これにより、非同期で値が変化するような処理でも、予期しない値の上書きを避けることができます。

まとめると、クロージャーはJavaScriptの関数スコープを理解する上で非常に重要な概念であり、イベントリスナーの効率的な管理、ボタンやフォームの状態追跡、非同期処理での値保持など、多くの場面で活用可能です。今回紹介したコード例を自分で実際に書き、動作を確認することで、クロージャーの仕組みと利便性をより深く理解できるでしょう。

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

生徒

「先生、クロージャーを使うとボタンや入力フォームの値をずっと覚えておけるってことですね?」

先生

「そうです。クロージャーは関数が持つメモ帳のようなもので、外側の変数を覚えて使える仕組みです。ボタンごとに独立したカウンターを作ったり、入力値を保持して送信時に使ったりできます。」

生徒

「非同期処理でも使えるんですよね?たとえば、クリック後に少し遅れて値を表示する場合とか。」

先生

「その通りです。setTimeoutPromiseの中でもクロージャーは変数を覚えているので、非同期でも正しい値を利用できます。」

生徒

「なるほど。即時関数や関数生成パターンを使えば、変数の管理も安全にできるんですね。」

先生

「そうです。クロージャーを理解すれば、イベントリスナーの管理が効率化され、複雑な処理もシンプルに書けます。まずは小さなボタンや入力フォームで試してみて、感覚を掴むことが大事です。」

生徒

「わかりました。今日学んだクロージャーの基本と応用を、自分でもコードを書きながら復習してみます!」

先生

「良いですね。クロージャーを使いこなすと、JavaScriptでのイベント処理や非同期処理がとても柔軟に、安全に書けるようになりますよ。」

カテゴリの一覧へ
新着記事
New1
JavaScript
JavaScriptのスコープとは?ローカル変数・グローバル変数の違いと使い分け
New2
TypeScript
TypeScriptで型の合成時に発生する型エラーの対処法を徹底解説!初心者にもわかりやすく解説
New3
TypeScript
TypeScriptでAPI呼び出しをラップするユーティリティ関数の設計完全ガイド!初心者向けにAxiosやFetchの使い方を解説
New4
TypeScript
TypeScriptのMapped Typesとインターフェースの連携方法を徹底解説!初心者でも理解できる型変換の基本
人気記事
No.1
Java&Spring記事人気No1
JavaScript
JavaScriptのループで無限ループが起きる原因と対策を初心者向けに徹底解説!
No.2
Java&Spring記事人気No2
JavaScript
JavaScriptのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.3
Java&Spring記事人気No3
JavaScript
JavaScriptの文字列の長さを取得する(lengthプロパティ)
No.4
Java&Spring記事人気No4
TypeScript
TypeScriptのファイル分割とimport/exportの基本を徹底解説!初心者でも安心のやさしい入門
No.5
Java&Spring記事人気No5
TypeScript
TypeScriptでコメントを書く正しい書き方と使い分け【初心者向けにやさしく解説】
No.6
Java&Spring記事人気No6
JavaScript
JavaScriptのプリミティブ型と参照型の違いを初心者向けに解説
No.7
Java&Spring記事人気No7
TypeScript
TypeScriptの始め方:開発環境の構築手順【初心者向け】
No.8
Java&Spring記事人気No8
TypeScript
TypeScriptでパスエイリアスを設定する方法!baseUrlとpathsでコードをスッキリ整理