]
上記のシナリオは初心者にとって一般的なものです。つまり、HTML 要素のコレクションを取得し、ループ内の要素にイベントを追加します。イベント応答関数(イベントハンドラ)で対応するインデックスを取得します。ただし、毎回、最後のループのインデックスを取得します。
その理由は、初心者はJavaScriptのクロージャ機能を理解していないからです。 element.onclick=function(){alert(i);} を通じて、クリック イベントを要素に追加します。応答関数 function(){alert(i);} の i は、各ループに対応する i (0、1、2、3、4 など) ではなく、ループ後の最後の i の値 5 です。 つまり、対応する値 i はループ中に応答関数に保存されませんでしたが、前回の i の値は 5 でした。
理由を理解し、多くの解決策を見つけました (単なる興味から)。最初に思いつくのは 2 つです
1. 各段落オブジェクトに変数 i を保存します (p)
コードは次のとおりです。
function init1() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i
pAry[i].i = i;
pAry[i].onclick = function() {
alert(this.i)
}
}
2. 変数 i を匿名関数自体に保存します
function init2() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i
(pAry[i].onclick = function() {
alert(arguments.callee.i);
}).i = i;
}
}
その後、さらに 3 つ考えました
3. クロージャの層を追加し、関数パラメータの形式で内部関数に i を渡します
function init3() {
var pAry = document.getElementsByTagName("p"); >for( var i=0; i
(function(arg){
pAry[i].onclick = function() {
alert(arg);
};
})(i); //呼び出し時のパラメータ
}
}
4. i が内部関数に渡されます。ローカル変数の形式
function init4( ) {
var pAry = document.getElementsByTagName("p");
for( var i=0; i
(function () {
var temp = i;//
pAry[i].onclick = function () {
alert(temp);
}
} を呼び出すときのローカル変数
5. クロージャーのレイヤーを追加し、応答イベントとして関数を返します (3 との微妙な違いに注意してください)
var pAry = document.getElementsByTagName("p");
for( var i= 0; i
pAry[i].onclick = function (arg) {
return function() {//関数
alert(arg) を返します。 }
}(i);
}
}
その後、さらに 2 つのタイプが発見されました
6. 実際には関数を使用して実装します。インスタンスが生成されると、クロージャが生成されます
コードをコピー
コードは次のとおりです: function init6() { var pAry = document.getElementsByTagName("p");
for( var i=0; i
pAry[i].onclick = new Function("alert(" i ");");//new は関数インスタンスを一度生成します
}
}
7. Function を使用して実装します。違いに注意してください。 with 6
コードをコピーします