0

重複の可能性:
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 番目のコード スニペット) が、この関数を定義する時点で定義された変数へのポインターを持つクロージャーで作成されているためですinfosi最初の例では、 2番目に加えてctrl

「閉鎖を回避」できれば、これを解決できると思います。つまり、クリック ハンドラ関数の実行時点ではなく、宣言時点の値で変数を参照したいと考えています。

これを達成する方法はありますか?または、おそらく、この問題に対するさらに優れた解決策はありますか?

4

0 に答える 0