1

参照によってクロージャに渡される変数。このコード:

var figs = ['circle', 'square'];
for (var i in figs) {
    var fig = figs[i];
    document.getElementById(fig).addEventListener("click", function(e) {
        console.log(fig);
    }, false);
}

クリックして丸を付けても、常に最後の配列要素をログに記録します(square 、 fig変数の最後の値)。

fig変数の実際の値をバインドするために、関数呼び出しでラッピングを使用します (したがって、中間クロージャーはループ値を保持します)。

var figs = ['circle', 'square'];
for (var i in figs) {
    var fig = figs[i];
    document.getElementById(fig).addEventListener("click", (function(fig) {
        return function(e) {
            console.log(fig);
        }
    })(fig), false);
}

値渡しのためにラッピング関数を避けることは可能ですか?

UPDATE関連の質問と回答:

4

2 に答える 2

4

いいえ、できません。

ただし、ループから内部関数を生成するコードを取り出すことで、コードを少し良くすることができます。

var figs = ['circle', 'square'];
function createFigHandler(fig) {
    return function(e) {
        console.log(fig);
    }
}

for (var i = 0; i < figs.length; i++) {
    var fig = figs[i];
    document.getElementById(fig).addEventListener("click", createFigHandler(fig), false);
}

jsフィドル

于 2013-11-11T15:17:24.067 に答える
2

bind必要な変数をカプセル化するオブジェクトを使用して渡すこともできます。次にthis.fig、ハンドラー内を使用して図を参照できます。

document.getElementById(fig).addEventListener("click", (function(e) {
     console.log(this.fig);
}).bind({ fig: fig }), false);

プリミティブ値を直接バインドすることもできますがNumber、数値やString文字列などの場合は、それぞれのオブジェクト ラッパーにラップされます。

document.getElementById(fig).addEventListener("click", (function(e) {
    //this will be the same as new String(fig)
}).bind(fig), false);
于 2013-11-11T15:21:08.953 に答える