Javascript閉鎖の理解

3232 ワード

例1:
function makeCounter() { var i = 0; console.log( ++i ); } var counter = makeCounter(); //   : 1 counter(); //TypeError: undefined is not a function counter(); //TypeError: undefined is not a function
この例では、makeCounter関数を宣言し、var counter=make Counter()を発見した.結果を出力しました.  これは実際には  賦値番号の右のMakeCounterは関数を一回実行しましたが、戻り値がないので、counterはundefinedを与えられました.次の2回の呼び出しはエラーTypeError:undefined is not a functionに戻ります.
 
修正後のコードを見てください.
例2:
function makeCounter() { var i = 0; return function() { console.log( ++i ); }; } var counter = makeCounter; //    counter(); //     counter(); //     var counter2 = counter(); //    counter2(); //   : 1 counter2(); //   : 2 var counter3 = makeCounter(); //    counter3(); //   : 1 counter3(); //   : 2  console.log(i); // ReferenceError: i is not defined
今回のmakeCounter関数の戻り値は関数です.ここでは実際にはクローズドされています.javascriptアドバンストプログラムの設計によると、クローズドとは別の関数の作用領域にアクセスできる変数の関数です.MDNによると:
Cloosures are functions that refer to independent(free)variables.
In other words,the function defined in the closure'remembers'the environment in which it created.
このように一つの関数の内部にもう一つの関数を作るということは、通常、クローズドを作成する最も一般的な方法です.
クローズドの関数は、その外側の環境を作成する活動対象を「覚えておく」ことができます.makeCount関数が実行した後、その活動対象は破壊されません.なぜなら、クローズド内の関数の作用領域チェーンはまだこの活動対象を参照しているので、メモリに保存されています.ゴミの回収角度から見ると、外部で環境を実行する活動対象はゴミとして回収されません.
上記のコードに示されているように、makeCount関数を呼び出すたびに、すなわち、毎回クローズドバックするたびに内部関数体は同じであるが、実行するたびに環境の活動対象は独立しており、互いに関連しないので、count 2()とcount 3()の出力を参照してください.
Javascriptの関数はすべてクローズドされています.関数ごとに関数以外のグローバル実行環境にアクセスできるからです.
 
次のページ:匿名関数とクローズド