簡體   English   中英

如何從setInterval調用函數?

[英]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);

}

DEMO

問題是內部的背景下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

thisundefined (在'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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM