では、JavaScriptのようなプロトタイプペースではどうするかという話。
呼び出すたびにカウントが1づつ増加していくcounter()という関数の例で考える。
何も考えずに作ると次のようになる。
var i = 0; function counter(){ i+=1; } counter(); //1 counter(); //2
問題は、変数iが関数の外に出ているがために、外部から簡単にアクセスできてしまうということ。
(グローバル変数は極力使いたくない)
オブジェクト指向でいうところの、変数の隠蔽をしつつ、この関数内だけで変数iを共有するためにはどうすればよいか?
ここでクロージャの出番となる。
var counter = (function(){ var i=0; return function(){ i+=1; }; })(); counter(); //1 counter(); //2
(function(){})()の部分で、無名関数を即実行する。
その結果counterに代入されるのは、return 以降に書かれている関数、
function(){i+=1};
である。では、このreturn文の前に書かれている var i=0;はどうなるか。
このiは最初に実行された後、消えず、全てのcounter()に共有され、参照されるようになる。
よって、counter()が呼ばれるたびにiは0に初期化されず、変更が反映される。
クロージャを使ってプライベート変数を共有する方法は、オブジェクトを作るときにも利用でき、
var counter = (function(){ var i=0; reuturn { inc : function(){ i += 1; }, dec : function(){ i -= 1; } }; })();
オブジェクト間で、共有する場合は基本的にこのパターン。
0 件のコメント:
コメントを投稿