1

我正在做这样的事情:

var talkAPI = {
    init: function(){
        setInterval(function(){
            this.speak();
        },1000);
    },
    speak: function(){
         //Something else
    }
};

但是,我发现这并没有像我预期的那样工作。所以我做了一些测试,我发现thisinsetInterval指的是Window. 这不是我想要的。那么我该如何重新this参考talkAPI?因为我不想这样做:

setInterval(function(){
    window.talkAPI.speak();    //Not so good
},1000); 
4

2 回答 2

5

您需要保存原件this以在回调中使用

init: function() {
    var self = this;
    setInterval(function(){
        self.speak();
    },1000);
},
于 2012-04-24T22:44:48.320 回答
2

问题在于,在 JavaScript 中,this完全由函数的调用方式定义,而不是函数的定义位置(就像在其他语言中使用该关键字一样)。所以setInterval调用你给它的函数的方式,this没有设置为任何特定的(因此默认为全局对象,它window位于浏览器上)。更多信息:你必须记住this

使用您引用的代码,您有两个选择:

  1. 正如 Kolink 评论的那样,由于您的对象是单例并且init函数关闭了talkAPI变量,所以没有任何理由不能只使用talkAPI

    var talkAPI = {
        init: function(){
            setInterval(function(){
                talkAPI.speak();    // <=== Only change is here
            },1000);
        },
        speak: function(){
             //Something else
        }
    };
    
  2. 更一般的答案,它适用于单例和由构造函数创建的对象等,是保留 的值this如 JaredPar 所述

    var talkAPI = {
        init: function(){
            var self = this;        // <=== Create a variable to close over
            setInterval(function(){
                self.speak();    // <=== Use it
            },1000);
        },
        speak: function(){
             //Something else
        }
    };
    

在这两种情况下,这些函数都有一个持久的、实时的链接到它们关闭的符号,这就是它们可以使用它们的原因。以这种方式绑定数据的函数称为闭包。更多:闭包并不复杂

于 2012-04-24T23:00:46.577 回答