1

「Javascript: The Good Parts」の本でクロージャーについて読んでいます。

クロージャーを使用する次の例があります。

var add_the_handlers = function (nodes) {
var i;
   for (i = 0; i < nodes.length; i += 1) {
      nodes[i].onclick = function (i) {
         return function (e) {
            alert(i + ":" + e);
         };
      }(i);
   }
};

正しい例ですか?または、多くの正しい例は次のようになりますか?

var add_the_handlers = function (nodes) {
var i;
   for (i = 0; i < nodes.length; i += 1) {
      nodes[i].onclick = function (idx) {
         return function (e) {
            alert(idx + ":" + e);
         };
      }(i);
   }
};

外部関数の変数 i と内部関数の変数 i "nodes[i].onclick = function (i)" - 2 つの異なる変数です。そして、3 番目の関数は、最も外側からではなく、2 番目の関数から変数にアクセスします。
私は正しいですか?

4

4 に答える 4

2

2 つの例は同一です。クロージャーの全体的なポイントは、外部スコープの変数 (i) を内部スコープの変数 (i/idx/foo から選択してください) にすることです。クロージャーは変数の「コピー」を作成するため、コールバックが行われたときに正しい値が設定されます。

// outer-scoped i changes on each iteration
var i;

for (i = 0; i < nodes.length; i += 1) {
   nodes[i].onclick = function (i) {

      // here i now refers to a different variable; while the outer i keeps iterating,  
      //this i is preserved at its current value.
      return function (e) {
         alert(i + ":" + e);
      };
   }(i);
}
于 2012-06-19T06:28:49.800 に答える
2

はい、正しい例です。関数パラメーターとして表示される変数は、ローカル スコープで宣言されているためi、外部変数よりも優先されます。i

于 2012-06-19T06:28:34.027 に答える
0

JavaScript の観点から見ると、これら 2 つは同一です。したがって、それは味の問題です。内部にさらに多くのクロージャーがある場合は、別の名前を使用することをお勧めします。しかし、ここでの例は非常に単純です。その必要はありません。

于 2012-06-19T06:28:46.977 に答える
0

いいえ、投稿した 2 つの例はまったく同じです。唯一の違いは、関数のパラメーター名だけですが、それは問題ではなく、何でも使用できます。

于 2012-06-19T06:30:22.480 に答える