0

クロージャーを理解して使用するのに苦労しています (はい、JavaScript クロージャーはどのように機能しますか?を読みました) 。

私の問題は次のとおりです。

for (row = 0; row < 10; row++) {
    for (column = 0; column < 10; column++) {

        var target = $("#" + Data.Row[row].Column[column].ID);

        target.mouseenter(function () {
            var position = CalculatePosition($(this));

            alert("row:" + row + ",column:" + column);

            ...
        });
    }
}

ご想像のとおり、ターゲットがマウスを上に置くと、行と列は常に 9 になります。私の質問は、mouseevent匿名関数が意図した値を取得できるように、行と列の値を固定するにはどうすればよいですか? 私は何かをやってみました

target.mouseenter(function() {}.bind(column));

そして、それは列だけでうまくいくようですが、もちろんthisもはやターゲットを参照していません。

4

2 に答える 2

5

ここでの最も簡単なオプションは、通常、ハンドラーを返す関数を定義することです。

function getHandler(row, column)
    return function () {
        var position = CalculatePosition($(this));
        alert("row:" + row + ",column:" + column);
        // ...
    };
}

次に、ループ内でこの関数を呼び出して、関連する変数が呼び出し時に値に「固定」されたハンドラーを取得します。

for (row = 0; row < 10; row++) {
    for (column = 0; column < 10; column++) {
        var target = $("#" + Data.Row[row].Column[column].ID);
        target.mouseenter(getHandler(row, column));
    }
}

ループ内で、すぐに実行される無名関数でこれを行うこともできます。

for (row = 0; row < 10; row++) {
    for (column = 0; column < 10; column++) {
        var target = $("#" + Data.Row[row].Column[column].ID);
        target.mouseenter((function(row, column) {
            return function () {
                var position = CalculatePosition($(this));

                alert("row:" + row + ",column:" + column);

                ...
            };
        })(row, column)));
    }
}

しかし、IMO はかなり見にくく、読みにくいものです。

いずれの場合も、ここでの基本的なアプローチは、ループ変数を引数として使用して、新しい関数スコープを確立することです。ハンドラー コールバックで使用すると、外部スコープ変数への参照ではなくなりました。

于 2013-07-22T22:30:52.420 に答える