簡體   English   中英

Javascript關閉凍結增量器的值

[英]Javascript closure freezing values of incrementer

我在理解和使用閉包方面花了很多時間(是的,我已經閱讀了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不再指目標。

通常,這里最簡單的選項是定義一個返回您的處理程序的函數:

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丑陋且難以閱讀。

無論哪種情況,這里的基本方法都是使用循環變量作為參數來建立新的函數作用域。 現在,當您在處理程序回調中使用它們時,它們不再是對外部作用域變量的引用。

您可以像這樣使用bind (第一個參數是上下文( this arg)):

target.mouseenter(function(row, column){
    ...
}.bind(target[0], row, column));

但是bind不是跨瀏覽器,並且您已經在使用jQuery,因此應該使用proxy代替:

target.mouseenter($.proxy(function(row, column){
    ...
}, target[0], row, column));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM