1

次のコードを検討してください。

for( var i = 1; i <= 2; ++i )
{
 $( '#id' + i ).click(
   function()
   {
     alert( 'ID = ' + i );
   }
  )
}

問題は、id1 または id2 がクリックされたときにアラートが常に ID = 3 と表示されることです。なぜこれが発生するのかがわかりました (呼び出し時に評価されます)。(1)

ここでの多くの質問と一般的な記事では、閉鎖の概念を非常によく説明していますが、それを回避する手法を見つけることができませんでした。

ちなみに、私は使用しようとしました(追加のキーワード「new」に注意してください):

new function() { alert( 'ID = ' + i ) }

ただし、アラートが定義された時点でアラートを直接呼び出し、クリック イベントに対しては何もしません。これについて何か考えはありますか?(2)

4

3 に答える 3

1

i基本的に、値が変わらない新しいスコープを作成する必要があります。説明のために、ループの外側に関数を作成して、現在の値を渡すことができます。

function createClickAction(i){
    return function(){
        alert( 'ID = ' + i );
    }
}

for(var i = 1;i <= 2; ++i){
    $( '#id' + i ).click(
        createClickAction(i)
    );
}

しかし、同じことを行うより短い方法は、値をIIFEに渡すことです:

for(var i = 1;i <= 2; ++i){
    (function(i){
        $( '#id' + i ).click(
            function(){
                alert( 'ID = ' + i );
            }
        );
    })(i);
}

ここでは、構文new function(){...}
についていくつか説明します。 これは、コンストラクタとして無名関数をインスタンス化するため、IIFE と同じ効果があります。つまり、次のように言います。

function Message(){
    alert('hi');
}
new Message();

...しかし、ネーミングなし。
そして引数を渡すには:

new function(msg){
    alert(msg)   
}('hi');

したがって、おそらくこの解決策を見つけるのに近かったでしょう:

for(var i = 1;i <= 2; ++i){
    new function(i){
        $( '#id' + i ).click(
            function(){
                alert( 'ID = ' + i );
            }
        );
    }(i);
}
于 2013-08-30T13:36:23.640 に答える
0

どうですか -

for( var i = 1; i <= 2; ++i )
{
 $( '#id' + i ).click(
   function()
   {
     alert( 'ID = ' + this.id.substring('#id'.length) );
   }
  )
}
于 2013-08-30T13:13:17.057 に答える