
【JavaScript入門】クロージャ
JavaScript の「クロージャ(closure)」は、関数内で定義した関数が、その外側のスコープにある変数を 取り込んで 参照または操作できる仕組みを指します。クロージャによって、外側の関数が終了した後も、内部関数が外部スコープの変数を保持し続けることが可能です。これにより、「関数が状態を保持する」ような設計ができ、さまざまな応用が可能になります。以下ではクロージャの基本的な例や、実践的な利用例を紹介します。

1.クロージャの基本
外側の関数(スコープ)にある変数や引数を、内側の関数が取り込んで利用できるという性質がクロージャです。内側の関数を外側から返すことで、外側のスコープが終わっても値を保持し続けます。
【myClosureExample.html】
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>myClosureExample.html</title>
</head>
<body>
<h1>クロージャのサンプル</h1>
<p>ブラウザの開発者ツールを開き、コンソールに注目してください。</p>
<script>
// 1. 基本的な例
function getFunc() {
// 外側関数の変数
const name = 'チョコレートパフェ';
// 内側関数 (この中で外側の変数を使う)
function innerFunc() {
// innerFunc内で宣言した変数
const price = 850;
console.log(`${name}:${price}円`);
}
// 内側関数を返す → これがクロージャ
return innerFunc;
}
// クロージャを取得
const func = getFunc();
// func() を実行すると、すでに外側関数 getFunc() は終わっているが、
// 取り込んだ変数 name を保持し、アクセスできる
func();
// 2. クロージャの応用例:呼び出し回数をカウント
function createCounter(label) {
let count = 0;
return function() {
count++;
return `${label}は ${count}回呼び出されました`;
};
}
const counterA = createCounter('A');
const counterB = createCounter('B');
console.log(counterA()); // Aは 1回呼び出されました
console.log(counterB()); // Bは 1回呼び出されました
console.log(counterA()); // Aは 2回呼び出されました
console.log(counterB()); // Bは 2回呼び出されました
console.log(counterB()); // Bは 3回呼び出されました
</script>
</body>
</html>
デバックコンソールの出力
チョコレートパフェ:850円
Aは 1回呼び出されました
Bは 1回呼び出されました
Aは 2回呼び出されました
Bは 2回呼び出されました
Bは 3回呼び出されました
解説
getFunc()
は内部にname
を定義しており、さらにinnerFunc()
という関数を返します。このinnerFunc()
が「クロージャ」と呼ばれるもので、name
(外側の変数)を参照しているため、getFunc()
を呼び出した後でもname
を保持し続けます。createCounter()
ではカウント用のcount
変数が閉じ込められ、返された内部関数でカウントを操作していきます。counterA
とcounterB
はそれぞれ独立したスコープを保持しているため、カウントが別々に記録されます。
2.クロージャのメリットと注意点
- メリット
・関数が終了した後も、外側の関数スコープで定義した変数を保持・操作できる。
・データのカプセル化により、特定の関数からしか値を変更できないようにするなど、情報隠蔽的な設計が可能。 - 注意点
・不要なクロージャを多用するとメモリを無駄に消費する場合がある。
・スコープが複雑になると、変数のライフタイムが把握しづらくなる。
まとめ
- クロージャ とは、関数が外部スコープの変数を取り込み、関数が呼び出し元のスコープから独立してもその変数を参照・変更できる仕組み。
- 複数のクロージャが同じ外部スコープを共有していると、それぞれが同じ変数を変更し合うことが可能になる。
- 呼び出し回数をカウントしたり、モジュール的に状態を隠蔽したりと、JavaScript ならではの設計パターンに広く活用される。
クロージャを理解することで、JavaScript のスコープチェーンや関数オブジェクトの動きがより鮮明になり、柔軟で強力なプログラミングが可能になります。