我定义了一个API
对象:
function API() {
var self = this;
return {
getRandomArticle: function() {
$.getJSON("http://en.wikipedia.org/w/api.php?action=query&generator=random&grnnamespace=0&prop=extracts&exchars=50000&format=json&callback=?", function (data) {
for(var id in data.query.pages) {
console.log(data.query.pages[id].extract);
}
});
},
repeatAPICall: function() {
self.getRandomArticle();
console.log(self);
setTimeout(self.repeatAPICall, 5000);
}
}
}
然后我使用window.test = new API();
实例化了API对象。
当我转到Chrome开发工具并致电window.test.repeatAPICall()
时,它会运行一次,然后失败并说TypeError: Object #<API> has no method 'getRandomArticle'
我怀疑递归调用的行为方式与我的预期不同,我做错了什么?
工作代码:
function API() {
var self = this;
self.getRandomArticle = function() {
$.getJSON("http://en.wikipedia.org/w/api.php?action=query&generator=random&grnnamespace=0&prop=extracts&exchars=50000&format=json&callback=?", function (data) {
for(var id in data.query.pages) {
console.log(data.query.pages[id].extract);
}
});
},
self.repeatAPICall = function() {
self.getRandomArticle();
console.log(self);
setTimeout(self.repeatAPICall, 5000);
}
return this;
}
window.test = new API();
答案 0 :(得分:1)
现在你已经修复了“自我”与“这个”,下一个更改是使用
self.getRandomArticle= ...
self.repeatAPICall=...
然后只返回self / this。这应该工作。现在,你有两个对象 - 这个和你返回的对象。
答案 1 :(得分:0)
您的主要问题是将this.repeatAPICall
传递给setTimeout
。在JavaScript中调用方法时,this
关键字指向调用它的对象:
var something = {
foo : function(){
return this;
}
};
something.foo(); //=> something
但是,如果将函数分配给另一个变量,则上下文会更改(到全局window
对象):
var something = {
foo : function(){
return this;
}
};
something.foo(); //=> something
var bar = something.foo;
bar(); //=> window
这就是上面发生的事情;你将函数的引用传递给setTimeout
,然后失去了正确的上下文。
相反,你需要传入一个保持上下文的函数;您可以使用self = this
语句,如下所示:
repeatAPICall: function() {
self = this;
self.getRandomArticle();
setTimeout(function(){
self.repeatAPICall();
}, 5000);
这会创建一个匿名函数,它会记住self
对象的状态(这就是JavaScript变量作用域的工作原理)。当调用该函数时,它可以调用repeatAPICall
作为该对象的方法,而不是作为没有上下文的函数。
接受的答案避免了必须这样做(每种方法都可以访问self
),但希望这可以解释为什么它不起作用。