调用setTimeOut's函数带有对象,出现意外结果

calling setTimeOut's function with object, unexpected result?

本文关键字:对象 结果 意外 setTimeOut 函数 调用      更新时间:2023-09-26

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

我们正在针对范围内的特定对象调用bark函数(而不是this.bark,它会使"this"指向window..),因此"this"应该设置为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);

setTimeout(ralph.bark, 2000)调用ralph.bark。它只是将函数的引用传递给setTimeout。CCD_ 4然后在延迟之后执行该功能。当它这样做时,它将类似于callback();,因此函数内的this将引用window

MDN文档中详细解释了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))。

另请参阅:如何在回调中访问正确的"this"/上下文?

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