重複の可能性:
Javascript: ループの閉鎖?
私は頭を包むことができないjavascriptクロージャーにいくつかの問題を抱えています...通常は本当に便利だと思いますが、今回は邪魔になっています。
私の問題
いくつかの情報を含むオブジェクトのリストがあります - と呼びましょうinfos
。の各オブジェクトにinfos
は、文字列プロパティと、コントロール オブジェクトを参照するtext
プロパティがあります。control
コントロール オブジェクトには (とりわけ) function プロパティがありますactivate
。のオブジェクトの例は次のinfos
ようになります。
var info = {
text: 'Some string',
control: {
activate: function() {
alert('activated!');
}
}
}
infos
ここで、オブジェクト内の情報に基づいて、いくつかの新しいオブジェクト (実際には、jQuery を使用した DOM 要素) をループして作成したいと考えていinfo
ます。
私はこのようなことを試しました:
for (var i in infos) {
$('<a>')
.attr('href', '#')
.text(infos[i].text)
.click(function() {
infos[i].control.activate(); // This is where I get problems
});
}
ここで、クリック ハンドラーを実行すると、何か (上記の例では通常は変数i
) がundefined
になり、例外が発生します。
次のバリアントも試しました。
for (var i in infos) {
var ctrl = infos[i].control;
$('<a>')
.attr('href', '#')
.text(infos[i].text)
.click(function() {
ctrl.activate(); // This is where I get problems
});
}
この場合、例外は発生しませんが、クリックしたアイテムに関係なく、アクティブになるのは常に最後のコントロールです。
これについての私の理解は、これまでのところ
JavaScript クロージャーを正しく理解していれば、これは、クリック ハンドラー関数 (2 番目のコード スニペット) が、この関数を定義する時点で定義された変数へのポインターを持つクロージャーで作成されているためですinfos
。i
最初の例では、 2番目に加えてctrl
。
「閉鎖を回避」できれば、これを解決できると思います。つまり、クリック ハンドラ関数の実行時点ではなく、宣言時点の値で変数を参照したいと考えています。
これを達成する方法はありますか?または、おそらく、この問題に対するさらに優れた解決策はありますか?