用对象调用setTimeOut&#39的函数,意外的结果?

时间:2014-04-14 00:24:33

标签: javascript

我正在尝试解决一个JS难题,但是我不确定为什么在setTimeOut函数中使用ralph.bark不起作用(不记录Ralph ..)?

我们正在调用关于范围内的特定对象的bark函数(与this.bark相反,这将使"这个"指向窗口...),因此"这& #34;应该设置为ralph不应该吗?有人可以解释为什么这不起作用?

var Dog = function( name ) {
    this.name = name;
}

Dog.prototype.bark = function() {
    console.log( this.name );
}

// make a new instance of a Dog
var ralph = new Dog('Ralph');

// make Ralph bark once immediately
ralph.bark();


// in 2 second we want Ralph to bark again
// this works

setTimeout(ralph.bark.bind(ralph), 2000);

// this does not work, WHY?
// setTimeout(ralph.bark, 2000);

2 个答案:

答案 0 :(得分:2)

setTimeout(ralph.bark, 2000) 调用 ralph.bark。它只是将函数的引用传递给setTimeoutsetTimeout然后在延迟后执行该函数。如果是这样,它将类似callback();,因此函数内的this将引用window

MDN documentation中详细解释了this的工作原理。


也许这会让它更清晰:

function bark() {
    console.log( this.name );
}

var Dog = function( name ) {
    this.name = name;
}

Dog.prototype.bark = bark;

现在,无论您setTimeout(ralph.bark, 2000);还是setTimeout(bark, 2000);都没有区别,因为ralph.barkbark指的是同一个功能。

函数是第一类对象。除非您明确这样做(.bind(ralph))。

,否则它们不属于任何东西或受其约束

另请参阅:How to access the correct `this` / context inside a callback?

答案 1 :(得分:2)

JavaScript绑定this的方式,你无法通过这样的功能。

以下内容会发生同样的事情:

var bark = ralph.bark;
bark();

幸运的是,JavaScript有一种方法可以将函数绑定到它们的this对象。试试这个:

setTimeout(ralph.bark.bind(ralph), 2000);

这实际上是以下内容的快捷方式:

setTimeout(function() { ralph.bark(); }, 2000);

有关详细信息,请参阅bind上的MDN文章:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind