我正在尝试解决一个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);
答案 0 :(得分:2)
setTimeout(ralph.bark, 2000)
调用 ralph.bark
。它只是将函数的引用传递给setTimeout
。 setTimeout
然后在延迟后执行该函数。如果是这样,它将类似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.bark
和bark
指的是同一个功能。
函数是第一类对象。除非您明确这样做(.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