簡體   English   中英

為什么需要匿名函數來使用setTimeout保留“this”

[英]Why is an anonymous function required to preserve “this” using setTimeout

我已經多次使用setTimeout傳遞一個函數作為參考,例如

setTimeout(someFunction, 3000);

在某些情況下,保存的值this我已經將其分配到前手的變量,但不明白為什么下面不工作:

var logger = {
    log: function() { 
        var that = this;
        console.log(that.msg); 
        setTimeout(that.log, 3000); 
    },
    msg: "test"
};

logger.log();

但是,使用匿名函數可以正常工作:

var logger = {
    log: function() { 
        var that = this;
        console.log(that.msg); 
        setTimeout(function() { that.log() }, 3000); 
    },
    msg: "test"
};

這不起作用,因為setTimeout使用this值作為全局對象而不是父對象調用函數。 你傳遞一個值到setTimeout功能-它不知道它是如何被訪問的,因此不能用正確的調用它this值(不像正常的變量,值this當你調用函數只被確定,除非this已經被綁定到使用特定值Function.prototype.bind )。

通過改變一個匿名函數,您使用的封閉訪問的價值that ,作為一種價值(函數的變量范圍被設定,當它被定義,而不是當它運行)呼吁時也是如此。

這就像你做這樣的事情:

var a = { b: function () { return this.foo; }, foo: 'proper' };
function test(arg) {
    return arg();
}
var foo = 'random';
console.log(a.b()); // proper
console.log(test(a.b)); // random

還有使用一個相關的問題thissetTimeout傳遞正確的“這個”背景下的setTimeout回調?

因為在第一種情況下,你只引用功能log那是內that物體,但其關系that丟失。 可以把它想象成setTimeout直接調用存儲的內存地址中的log方法和全局上下文。

在第二個例子但是你來自全球范圍內,但首先that是抬頭,事后log其與上下文稱為然后that

可以認為setTimeout具有以下結構:

var setTimeout = function (func, time) {
   someWaitMechanism(time, function () { //this is called after the timeout
       func.call(null); //calls func with global scope
   });
}

暫無
暫無

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

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