2

JavaScript コードの 1 つに少し問題があります。ここにコードがあります

//assume array is an array containing strings and myDiv, some div in my doc
for(var i in array) {
    var myString = array[i];
    var a = document.createElement('a');
    a.innerHTML = myString;
    a.addEventListener("click", function() {myFunc(myString)}, false);
    myDiv.appendChild(a)
}
function myFunc(s) {alert(s);}

ただし、JavaScript では文字列は参照によって渡されるため、問題arrayのリンクをクリックすると常に最後の文字列が表示aされます。したがって、私の質問は「どうすればmyString値を渡すことができますか?」です。ご協力ありがとうございました !フィル

4

3 に答える 3

2

プリミティブ変数は、Javascriptでは参照によって渡されません。

これは、「クロージャ内で呼び出されるループ変数」問題です。

この問題に対して一般的に使用される解決策の1つを次に示します。

for (var i = 0, n = array.length; i < n; ++i) {
    var myString = array[i];
    var a = document.createElement('a');
    a.innerHTML = myString;
    a.addEventListener("click", make_callback(myString), false);
    myDiv.appendChild(a)
}

function make_callback(s) {
     return function() {
         alert(s);
     }
}

これは、配列内のすべての要素に対して新しい関数スコープを作成するため、特にメモリ効率が高くないことに注意してください。

より良い解決策は、変数データを実際に要素に(つまり、新しいプロパティとして)格納し、それをコールバックで取得することです。実際、その文字列はすでに.innerHTMLプロパティに格納されているので、それを読み取ってから、委任を利用して、要素の親に1つのハンドラーだけを登録できます。

for (var i = 0, n = array.length; i < n; ++i) {
    var a = document.createElement('a');
    a.innerHTML = array[i];
    myDiv.appendChild(a)
}

myDiv.addEventListener('click', function(ev) {
    alert(ev.target.innerHTML);
}, false);
于 2012-08-13T15:13:06.077 に答える
2

イベントハンドラの周りにクロージャを追加する必要があります。

ループ内のJavaScriptクロージャ–簡単な実用例

a.addEventListener("click", function (s) {
    return function () {
        alert(s)
    };
}(myString), false);

for...inまた、配列でループを使用しないでください。

于 2012-08-13T15:13:36.857 に答える
-1

これを試してください:for...inを使用して配列を反復することは常に良い習慣ではないと思います

for(var i=0; i<array.length;i++) {
    var myString = array[i];
    var a = document.createElement('a');
    a.innerHTML = myString;
    a.addEventListener("click", function() {myFunc(myString)}, false);
    myDiv.appendChild(a)
}
function myFunc(s) {alert(s);}
于 2012-08-13T15:13:55.323 に答える