[英]How to call a function from `setInterval`?
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)
為什么當我不使用setInterval
調用時this.func2
是函數,而當我從setInterval
調用時為什么不是函數?
因為在您的情況下,這不是指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();
也許您想做這樣的事情:
function Obj() {
this.func1 = function() {
this.func2();
},
this.func2 = function() {
setInterval(function(){
this.func2();
}.bind(this), 200);
}
}
但這很快就會導致溢出,因為您每次執行都會創建一個新的間隔。 也許您想使用setTimeout
?
你可以綁定 this
this.func2 = function() {
setInterval(function() {
this.func2();
}.bind(this), 200);
}
問題是內部的背景下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
函數將this
作為self
的參數self.func2()
,然后在其中使用self.func2()
。
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()
使用箭頭功能:
this.func2 = function() { setInterval(() => { this.func2(); }, 200); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.