2

このコード行を使用して、forloop によって作成された div にイベント リスナーを追加します。

for(var i in mail){
   //create div
   parent.addEventListener("click",function(){read_msg(mail[i].id);},false);
   //append to parent
}

mail[i].idこれは、それらすべての最後の ID になるという問題を引き起こしています。それを解決する方法の例をいくつか読みましたが、それでも非常に混乱しています。

私は次の解決策を提案されました:

(function(){read_msg(mail[this].id)}).bind(i);

read_msgしかし、これは使用するのに最適なソリューションではないと言われています.の正しい値を保持する方法を誰かが説明できることを望んでいましたidか? 解決策に関しては、常に少し面倒に思えます。

4

3 に答える 3

1

iこれは、イベント ハンドラー関数でクロージャー変数を使用しているためです。

変数iは外部関数のスコープ内に存在します。つまり、変数のインスタンスは 1 つだけですi。ハンドラ メソッドが呼び出されiてアクセスされると、javascript は最初にハンドラ関数のスコープを調べます。そこで変数が見つからない場合は、親クロージャ スコープを調べてから、親スコープで変数を見つけます。

親スコープでは、ループの実行中に値が の値を変更し続けるためi、すべてのコールバックが に対して同じ値を持ちますi

ここでの解決策は、ローカル クロージャーを作成することです。

for(var i in mail){
    (function(myvar){
        parent.addEventListener("click",function(){read_msg(mail[myvar].id);},false);
        //append to parent
    })(i);
}

ここで行っているのは、すぐに呼び出される関数式があり、これに の値をiparameter として渡していることmyvarです。したがって、ループ内の各反復は、独立したクロージャーを作成します。

于 2013-06-13T03:17:24.193 に答える
0

各ループ反復でイベント ハンドラーとして定義する各無名関数は、他のすべての関数と同じスコープを共有するため、それらはすべて、表示しようとしているメッセージの配列アドレスとして同じ var (i) を参照します。ループごとに var i を再定義しているため、i に割り当てられた最後の値が「メール」配列の長さになるため、クリック イベントごとに表示されるメッセージ配列の最後のメッセージが常に表示されます。

それを修正する方法は次のとおりです。

var helper = function(index) {
    parent.addEventListener("click", function(){read_msg(mail[index].id);},false);
}

for(var i in mail) {
    helper(i);
}
于 2013-06-13T03:55:42.777 に答える