クロージャの概要
クロージャとは。
- 関数を入れ子にする
- 外側の関数をエンクロージャ、内側の関数をクロージャと言う
- エンクロージャはクロージャへの参照を返す
- この参照を保持することで、関数呼び出し時のコンテキストがメモリ上から解放されないようにする
- これによりエンクロージャ内で定義した変数が永続化される
- ただしエンクロージャ内に定義した変数にアクセスできるのはクロージャのみである
- コンテキストはエンクロージャの呼び出し毎に異なる
典型的なクロージャの例
function fn(n) { // エンクロージャ
return function() { // クロージャを返す
return ++n; // nは同じコンテキストで共有
}
}
var f1 = fn(0); // fnコンテキストの生成(1)
var f2 = fn(10); // fnコンテキストの生成(2)
console.log(f1()); // =>1
console.log(f2()); // =>11
console.log(f1()); // =>2
console.log(f2()); // =>12
クロージャの使いどころ
- クラス/オブジェクトのカプセル化
[JavaScript]クラス、関数、オブジェクト - Qiita
クロージャのデメリット
- 実行速度の低下
- メモリリーク
以下はMozillaのドキュメント。
クロージャの良くない副作用として、Internet Explorer で簡単にメモリリークを発生させることがあります。JavaScript はガベージコレクトを行う言語です。オブジェクトは生成時にメモリが割り当てられ、オブジェクトへの参照がなくなったときにメモリがブラウザによって回収されます。ホストの環境から提供されるオブジェクトは、その環境に管理されます。
via JavaScript 「再」入門 - JavaScript | MDN
また、GoogleのJavaScript規約では次のように書いている。
使っても良い. ただし慎重に. クロージャは JavaScript の中でも最も便利でよく見る機能です. クロージャについて詳しくはこちらを参照してください. ただし一点注意すべき点は, クロージャはその閉じたスコープへのポインタを保持しているという点です. そのため, クロージャを DOM 要素に付加すると循環参照が発生する可能性があり, メモリリークの原因となります.
via Google JavaScript Style Guide 和訳 — Google JavaScript Style Guide 和訳
参考URL
JavaScript のスコープチェーンとクロージャを理解する - tacamy.blog
クロージャの復習 | blog.makitasako.com
[JavaScript]クロージャをファクトリーパターンとして理解する by Utage Blog
JavaScriptのクロージャはどういった場合に利用するのでしょうか。どんな場合にメ... - Yahoo!知恵袋