私はJSを学ぼうとしていますが、問題があります。
私は多くのことを試し、グーグルで検索しましたが、すべて無駄でした。次のコードは期待どおりに機能しません。クリックでiの値を取得する必要がありますが、常に6が返されます。髪を引っ張っています。
for (var i = 1; i < 6; i++) {
console.log(i);
$("#div" + i).click(
function() {
alert(i);
}
);
}
これは、従来のJavaScriptクロージャーの問題です。 i
オブジェクトへの参照は、i
の実際の値ではなく、クリックハンドラークロージャーに格納されています。
単一のクリックハンドラは同じオブジェクトを参照します。これは、6を保持するカウンタオブジェクトが1つしかないため、クリックごとに6を取得するためです。
回避策は、これを匿名関数でラップし、引数としてiを渡すことです。プリミティブは、関数呼び出しの値によってコピーされます。
for(var i=1; i<6; i++) {
(function (i) {
$("#div" + i).click(
function () { alert(i); }
);
})(i);
}
[〜#〜] update [〜#〜]
または、var
を宣言する代わりにi
の代わりに 'let' を使用できます。 let
は毎回新しいバインディングを提供します。 ECMAScript 6でのみ使用できますstrict mode
。
'use strict';
for(let i=1; i<6; i++) {
$("#div" + i).click(
function () { alert(i); }
);
}
問題は、ループを反復すると、i
が増加することです。 alert(i)
と言うと、javascriptにi
の値が何であるかを伝えるように求めています。リンクをクリックします。その時点では6です。
代わりにボックスの内容を取得する場合は、次のようなことができます。
for (var i = 1; i < 6; i++) {
console.log(i);
$("#div" + i).click(function(e) {
alert($(this).text());
});
}
$("#div" + i).click(
function() {
alert(i);
}
);
i
の値をクロージャーとして使用しているためです。 i
は、foorループのすべての段階で増加するクロージャーを通じて記憶されます。
$("#div" + i).click(function(event) {
alert($(event.target).attr("id").replace(/div/g, ""));
});