function Obj() {
this.func1 = function() {
this.func2();
},
this.func2 = function() {
setInterval(function() {
this.func2();
}, 200);
}
}
function main() {
var obj = new Obj();
obj.func1();
}
main();
我有以下例外:
this.func2(); ^ TypeError: this.func2 is not a function
at Timeout._onTimeout(C: \Users\ Admin\ Desktop\ CANVAS\ test.js: 15: 12)
at ontimeout(timers.js: 365: 14)
at tryOnTimeout(timers.js: 237: 5)
at Timer.listOnTimeout(timers.js: 207: 5)
为什么this.func2
在没有setInterval
的情况下通话时功能正常,而且在我从setInterval
拨打电话时不是功能?
答案 0 :(得分:0)
因为在你的情况下这并不是指Obj。该上下文已更改,这是指setInterval上下文。
取消var self = this;
行,其中存储this
以供日后使用。
这应该有效
function Obj() {
this.func1 = function() {
this.func2();
},
this.func2 = function() {
setInterval(function(){
self.func2();
}, 200);
}
}
function main() {
var obj = new Obj();
obj.func1();
}
main();
答案 1 :(得分:0)
也许你想做这样的事情:
function Obj() {
this.func1 = function() {
this.func2();
},
this.func2 = function() {
setInterval(function(){
this.func2();
}.bind(this), 200);
}
}
但是这很快就会导致溢出,因为你在每次执行时都会创建一个新的间隔。也许您想使用setTimeout
?
答案 2 :(得分:0)
您可以绑定 this
this.func2 = function() {
setInterval(function() {
this.func2();
}.bind(this), 200);
}
答案 3 :(得分:0)
问题是setTimeout
内的上下文是顶层,而不是对象的上下文,因此this
将指向window
(在浏览器中)而非您的宾语。有几种方法可以解决这个问题。
最新版本是使用bind
方法绑定函数的上下文。
function Obj() {
this.func1 = function() {
this.func2();
},
this.func2 = function() {
console.log('hi');
setTimeout(this.func2.bind(this), 1000);
}
}
function main() {
var obj = new Obj();
obj.func1();
}
main();

请注意,我使用this.func2.bind(this)
作为setTimeout
的回调(对于setInterval
也是如此,如果我将其保留下来,那么您的示例将非常垃圾)。这意味着无论在何处召唤,它的this
始终都是您的对象。
稍微更老的方法是将其包装在自我调用函数中,并将其隔离到this
设置为对象的范围。
function Obj() {
this.func1 = function() {
this.func2();
},
this.func2 = function() {
console.log('hi');
setTimeout((function(self){
return function () {
self.func2();
}
})(this), 1000);
}
}
function main() {
var obj = new Obj();
obj.func1();
}
main();

这种方式更复杂,但基本上我只是将你原来在自this
作为self
的参数传递的自调用函数中包含的内容,然后我使用{{1在它内部。
答案 4 :(得分:0)
this
未传递给您的setInterval
回调,因为它始终在全局上下文中调用,就像您使用setTimeout
时一样。
this
是undefined
(在'use strict'
模式下)或window
对象(在常规/宽松模式下)。您可以将额外的参数传递给setInterval
,然后将这些参数传递给您的回调:
this.func2 = function() {
setInterval(function(self) {
self.func2()
}, 200, this)
}
function Obj() {
this.func1 = function() {
this.func2()
}
this.func2 = function() {
setInterval(function(self) {
console.log(typeof self.func2) //=> 'function'
}, 200, this)
}
}
function main() {
var obj = new Obj()
obj.func1()
}
main()
答案 5 :(得分:0)
使用箭头功能:
this.func2 = function() {
setInterval(() => { this.func2(); }, 200);
}