部分的なアプリケーションを使用してデータをコールバックに渡す必要がありましたが、その後のループの実行によってコールバックに渡すデータが変更されないようにするために、間接レイヤーが必要であることがわかりました。
非常に単純な作業例については、こちらを参照してください: http://jsfiddle.net/s5gVj/
(jsfiddleが自明である場合は、以下の質問に直接スキップしてください)
間接性なしで
これにより、ラベルは常に「ボタン 1 が押されました」に設定されます。
これは、どのボタンが押されたかに関係なく発生します。
for(var i = 0 ; i < buttons.length ; i++)
{
var buttonID = i;
$(buttons[i]).click(
function(e)
{
$("label").html("Button " + buttonID + " pressed.");
});
}
関数を介して間接的に
一方、途中で関数を使用すると問題が修正されます
最初のボタンの場合、結果は「ボタン 0 が押されました」になります。
2番目のボタンの場合、「ボタン1が押されました」になります。
var buttonClickHandlerWithID =
function(buttonID)
{
return function(e)
{
$("label").html("Button " + buttonID + " pressed.");
}
}
for(var i = 0 ; i < buttons.length ; i++)
{
$(buttons[i]).click(buttonClickHandlerWithID(i));
}
なぜこれが起こるのですか?変数がコピーされ、同じデータへの参照がなくなることを保証する関数呼び出しに何か特別なことがありますか?それとも何か他のことが起こっていますか?
for ループ内で宣言された変数が各反復で再作成されることを期待していたので、各反復は個別に行われますが、そうではないと思いますか?