簡體   English   中英

對javascript中的'this'關鍵字感到困惑

[英]Confused about the 'this' keyword in javascript

我已經很久沒有使用Javascript了,今天一直在刷新自己。 總是讓我着迷的一件事是this關鍵字。 我知道在jQuery事件處理程序(例如click事件)中, this是指觸發事件的元素。 即使我的函數沒有參數, this如何傳遞給作為回調的函數?

給出以下代碼:

$("tr.SummaryTbRow").data("Animating", false);
$("tr.SummaryTbAltRow").data("Animating", false);

$("tr.SummaryTbRow").click(function () {
    if ($(this).data("Animating") == false) {
        if ($(this).next(".Graph").css("display") == "none") {
            $(this).data("Animating", true);

            //Part I am questioning.
            setTimeout(function () {
                $(this).data("Animating", false);
            }(this), 550);

            $(this).next(".Graph").slideRow('down', 500);
        }
        else {
            $(this).data("Animating", true);
            $(this).next(".Graph").slideRow('up', 500);
        }
    }
});

我試圖弄清楚如何將帶有類SummaryTbRow的元素表行SummaryTbRow給我的setTimeout回調函數。 jQuery是否以類似於我使用匿名回調函數的方式傳遞了this 我的函數內的this是否指代我傳入的this

我知道我可以做:

setTimeout(function (element) {
    $(element).data("Animating", false);
}(this), 550);

但是,我想弄清楚的jQuery是如何能夠通過this我的回調函數,即使我的函數接受0參數。

為了回答您的最后一個問題,您可以將您選擇的接收者傳遞給javascript中的函數,用於示例調用

someFunction.call(someObject);

someFunction內部, this將是someObject

就您而言,您似乎想要的是

setTimeout(function (element) {
    $(element).data("Animating", false);
}, 550, this); // this will be passed as element to the callback

或( 更兼容

var _this = this;
setTimeout(function () {
    $(_this).data("Animating", false);
}, 550); 

簡短答案:

您可以設置this使用功能的上的功能.call().apply()方法。

長答案:

任何函數上的this變量都類似於arguments變量(這可能是您所不知道的)。 它是在調用函數時設置的,它是函數調用方式的構件。 為了解釋,讓我從arguments 考慮:

myFunction = function () {
    return arguments.length;
};

現在,讓我們看一下對myFunction的幾個調用:

myFunction(); //is 0
myFunction(null); //is 1
myFunction(undefined); //is 1
myFunction(0, 0, 0, 0, 0); //is 5

正如你所看到的,價值arguments.length不依賴於如何或在哪里我們寫的功能,但我們如何調用該函數。 this變量(也稱為“調用對象”)也是如此。 設置調用對象的方法恰好有3種(ES5中大約有4種,但我們將忽略它):

  1. 您可以通過使用點符號調用函數來設置它(例如, something.myFunction()
  2. 您可以通過使用該功能的設置.call().apply()方法(如myFunction.call(someObject)
  3. 如果未使用方法1或方法2進行設置,則默認使用全局對象(例如window

因此,大多數人習慣於方法1。 如果將函數分配為對象的屬性,然后使用對象和點符號調用函數,則對象將設置為this 像這樣:

var myFn = (function () { return this.x });

var myObj = {
    x: 1,
    y: myFn
};

myObj.myFn(); //is 1

但是,如果myFn不是我們要調用的對象的屬性,但是該對象遵循正確的形式使myFn可以對其執行操作,則我們也可以使用方法2(請參閱:鴨子鍵入):

var myOtherObj = {
    x: 2
}

myFn.call(myOtherObj); //is 2
myFn.apply(myOtherObj); //is 2
myFn.apply({ x : 3}); //is 3

很酷吧? jQuery就是這樣做的。 當他們執行回調函數,他們這樣做用.apply(event.target)設置this到事件的目標對象)。 由於使用了callbacks框架,因此它們以更復雜的方式進行操作, 但是這個想法就存在了

無論如何,如果我不扔方法3的解釋,那我就不會給出很長的答案,這使一些人完全發瘋:如果不設置調用對象會發生什么?

因為所有全局變量都是全局對象的隱式屬性,所以您可以從方法3中獲得一些有趣的效果。 如:

var x = 4;
myFn(); //is 4

但是大多數時候,您不是很幸運地使您的全局對象滿足函數對其調用對象的要求,因此通常只會導致錯誤和很多挫敗感。

可能比您期望的要多,但希望您現在對調用對象及其巧妙的方式有了更多的了解。

您可以使用fn.callfn.apply調用函數,這兩個函數都帶有用於this的上下文參數。

Applycallbind方法用於此目的。 就您而言,您只需編寫:

setTimeout(function() {
  $(this).data("Animating", false);
}.bind(this), 550);

暫無
暫無

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

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