閉鎖とは、別の関数範囲内の変数にアクセスする許可を持つ関数を指しますが、スコープ構成メカニズムは注意を払う必要があります。つまり、閉鎖は関数の変数を含む最後の値を取得することのみです。
次の場合のように:
function create(){var arr = new array(); for(var i = 0; i <10; i ++){arr [i] = function(){return i;}; } return arr;} var c_arr = create(); }実行結果:
表面的には、各関数によって返されるI値は異なるようです。たとえば、C_ARR [0]の値は0、C_ARR [1]の値は1などである必要があります。各関数は10を返すことで取得できます。なぜですか?
各関数のスコープチェーンは、create()関数のアクティブオブジェクトを保存するため、すべて同じ変数iを参照します。 forループが終了すると、iの値は10になります。この時点で、各関数は変数iを保持する同じ変数オブジェクトを指します。
別のドメイン関数を作成することにより、予想どおりに閉鎖を強制することができます。そうすれば、各位置が対応する値に対応します。
function create(){var arr = new array(); for(var i = 0; i <10; i ++){arr [i] = function(num){return function(){return num; };}(私); } return arr;} var c_arr = create(); }実行結果:
匿名関数を定義し、匿名関数をすぐに実行して配列に割り当てます。ここで、匿名関数にはパラメーター数があり、これは最終関数によって返される値です。各関数を呼び出すと、変数iに渡されます。関数パラメーターは値で渡されるため、変数Iの現在の値はパラメーターnumに割り当てられます。この匿名関数内では、閉鎖にアクセスするnumが作成および返されるため、arr配列内の各関数に独自のnum変数のコピーがあるため、独自の異なる数値値を返すことができます。
古典的な例
古典的な例を見てみましょう。ページにボタンタグのセットがあるとします。スクリプトを使用して、クリックイベントをこのボタンタグのセットにバインドし、クリックすると、どのタグがポップアップ表示されます。
<Meta charset = "utf-8"/> <butth> first </button> <butth> second </button> <butth> 3番目の</button> <butth> fourth </button> <script type = "text/javascript"> var obj = document.getelementsbytagname( 'button'); function(){alert(i);}; } </script>[各ボタン]をクリックして結果を出します
表面的には、各ラベルをクリックすると、異なる数字がポップアップ表示されるはずです
最初のものは0をポップアップする必要があります。
2番目のものは1ポップアップする必要があります。
等々。
しかし、その結果、すべてのボタンがポップアップします。これは明らかに私たちが望む結果ではありません。
プログラムを変更しましょう
<Meta charset = "utf-8"/> <butth> first </button> <butth> second </button> <butth> 3番目の</button> <butth> 4番目</button> <script type = "text/javascript"> var obj = document.getelementsbytagname( 'button'); function(){alert(num);}}(i); } </script>2番目のものをクリックします
4番目をクリックします
関数に匿名関数を作成するだけで、これは上記の場合と同じです。匿名関数を実装して外部変数Iをキャプチャでき、各ボタンポップのi値は異なります。