"这"在setTimeout中,自执行功能未定义

时间:2016-02-08 15:54:39

标签: javascript settimeout

我知道setTimeout中的这个默认对应于window,所以我一直在使用bind并将它传递给自执行函数,但是当setTimeout最终运行时(在第一次运行时它很好,调用通过TeaBot._manageTeaRound(),但它在自动执行时并不好)这是未定义的。这是我的代码,我哪里错了? (我删除了一些可能不相关的代码行)。谢谢你的帮助:)

TeaBot.prototype._manageTeaRound = function(originalMessage, channel){
    var self = this;
    self.teaMaker = this._getUserById(originalMessage.user);

    //now wait 3 minutes for people to send their order
    self._runTimer(self,channel);
}
TeaBot.prototype._runTimer =function(self, channel) {
    // do stuff
    console.log(self.teaMaker.name); //undefined

    var interval = self.interval,
        teaMaker = self.teaMaker;

    console.log("self.interval is " + self.interval);

    if(interval === 0){

        interval++;
        self.interval = interval;

        setTimeout(self._runTimer.bind(self, channel), 180000);

    }else{
        self.interval = 0;
    }
}

2 个答案:

答案 0 :(得分:1)

这一行存在问题:

setTimeout(self._runTimer.bind(self, channel), 180000);

函数TeaBot.prototype._runTimer期望self成为第一个参数 - Function.prototype.bind()第一个参数是context(函数' s this)。尝试使用它:

setTimeout(self._runTimer.bind(self, self, channel), 180000);

或者context为空,因为您根本没有使用this

setTimeout(self._runTimer.bind(undefined, self, channel), 180000);

答案 1 :(得分:0)

这是因为您使用this内的_runTimer值。您绑定了值this,但_runTimer无法关注。

_runTimer关心它的两个参数。第一个是上下文(self)。您的代码的结构方式,没有理由在这里使用.bind

setTimeout(function(){
    self._runTimer(self, channel);
}, 180000);

(由于您将上下文(self)传递给函数,因此_runTimer成为TeaBot.prototype的一部分是没有意义的,因为它需要传递给它的上下文。)

作为替代方案,您可以删除self参数,并_runTimer引用this。那时你需要来使用.bind()

TeaBot.prototype._manageTeaRound = function(originalMessage, channel){
    this.teaMaker = this._getUserById(originalMessage.user);

    //now wait 3 minutes for people to send their order
    this._runTimer(channel);
};
TeaBot.prototype._runTimer = function(channel) {
    // do stuff
    console.log(this.teaMaker.name);

    var interval = this.interval,
        teaMaker = this.teaMaker;

    console.log("this.interval is " + this.interval);

    if(interval === 0){

        interval++;
        this.interval = interval;

        setTimeout(this._runTimer.bind(this, channel), 180000);

    } else{
        this.interval = 0;
    }
};