当与setTimeout一起使用时,为什么javascript方法与对象松散连接

时间:2013-09-04 17:26:54

标签: javascript this

下面的代码打印出来:

timedout false undefined

即。 this不再在方法theActivityTimer中引用timedOut()。我想知道为什么会这样。

var theActivityTimer = {
    timer: "",          
    active: false,       

    refresh: function () {
        theActivityTimer.timer = setTimeout(
            this.timedOut,
            5000     
        );
    },

    timedOut: function(){
        alert("timedout " +
            theActivityTimer.active + " " + this.active);
    }
}

theActivityTimer.refresh();

http://jsfiddle.net/spiderplant0/nQ4XX/

有没有办法让它与this

一起使用

3 个答案:

答案 0 :(得分:3)

这个问题一直在问;您需要使用fn.bind

var theActivityTimer = {
    timer: null,          
    active: false,       

    refresh: function () {
        this.timer = setTimeout(this.timedOut.bind(this), 5000);
    },

    timedOut: function(){
        alert("timedout " + this.active);
    }
};

来自fn.bind文档

  

创建一个新函数,在调用时,将其this关键字设置为提供的值,并在调用新函数时提供任何前面提供的给定参数序列。


<强>声明:

fn.bind已在ECMAScript 5 中实施。如果您在浏览器中使用此功能并需要支持旧版本,请查看es5-shim


答案 1 :(得分:3)

this基于如何调用该方法。

foo.bar(); // this === foo

var bar = foo.bar();
bar() // this === window (defaults to global object)

所以setTimeout有效地做了后者。

相反,通常会传递一个匿名函数来维护对实例方法的正确调用。请记住,匿名函数也会丢失this,因此您需要将this保存到局部变量,这也很常见。

var self = this;
theActivityTimer.timer = setTimeout(function() {
    self.timedOut()
}, 5000);

还有其他方法来操纵上下文(this的值),但这可能是最容易理解和最广泛支持的。

答案 2 :(得分:0)

我想为此线程添加另一个解决方案,以添加不需要任何额外工作或库的内联解决方案,并且是跨浏览器。

var theActivityTimer = {
    timer: "",          
    active: false,       

    refresh: function () {
         theActivityTimer.timer = setTimeout(function() {
             theActivityTimer.timedOut();
         }, 5000);
    },