では、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 件のコメント:
コメントを投稿