1

私は知っています、素晴らしいタイトルです;-)

とにかく、次のコードがあるとしましょう(私はそうしています):

function GetArray(i) {
    if (i == 0) {
        return [1, 2, 3];
    }
    return [];
}

for (var i = 0; i < 3; i++) {
    var array = GetArray(i);

    var onClick = function() {
        alert(array.length);
    }

    var html = "<a>click me</a><br/>";
    var element = $(html);
    $("div").append(element);

    element.click(onClick);
}​

ここで作業コードを参照してください

3 つのリンクをクリックすると、それぞれの値が 0 のアラートが表示されます。

私が欲しいのは、最初のリンクがクリックされたときに 3 を警告することです。

さて、皆さんがなぜこれが起こっているのかを叫び始める前に、 onClick 関数が配列の同じインスタンスへの参照を使用してクリアしていることがわかります。したがって、ループの各反復は、新しい配列を作成するのではなく、配列を「変更」します。 、これが事実上、最後の配列値がすべてのクリック イベントに使用される理由です。

問題は、その仕事を成し遂げるために何ができるかということです。

関数内の配列を「複製」しようと考えましたが、それは機能しませんでした (私は を使用.slice(0)しました)。おそらく正しく機能しません。さらに、まったく同じ関数が 3 つのイベントすべてに使用されているだけかもしれません。

4

1 に答える 1

2

これが発生するときはいつでも、それはスコーピングの問題です。配列を通過するたびに、配列をonClickハンドラーにロックインする必要があります。これを行うには、自己呼び出し関数を介してその周囲にクロージャを作成します。

for (var i = 0; i < 3; i++) {
    var array = GetArray(i), onClick;

    // create a closure around onClick and array
    (function(array){
        onClick = function() {
            alert(array.length);
        }
    })(array);

    var html = "<a>click me</a><br/>";
    var element = $(html);
    $("div").append(element);

    element.click(onClick);
}​

2回目と3回目はリープを介して空の配列を返すため、これは3、0、0に警告することに注意してください。

于 2012-05-09T14:49:14.207 に答える