setTimeout() inside JavaScript Class using “this”

2020-01-24 20:59发布

I am trying to use setTimeout() inside a class function in JavaScript. The setTimeout() is supposed to trigger another method in the same Class, so the function I am passing it is written as window.setTimeout("this.anotherMethod", 4000). That bring the problem: this references the calling Object, in the case of setTimeout() it is window. How can I use enclosures to return a reference to the Class Object itself?

myObject = function(){

this.move = function(){
    alert(this + " is running");
}
this.turn = function(){
    alert(this + " is turning");
}
this.wait = function(){
    window.setTimeout("this.run" ,(1000 * randomNumber(1,5)));
}

this.run = function(){
    switch(randomNumber(0,2)){
        case 0:
            this.move();
        break;
        case 1:
            this.turn();
        break;
        case 2:
            this.wait();
    }
}

}

13条回答
Root(大扎)
2楼-- · 2020-01-24 21:50

Ran into a more complex situation...class A has a member of type B and a method that calls setTimeout which calls a method on class B. Solved as follows:

class A {
    constructor(b) {
        this.b = b;
    }
    setTimer(interval) {
        setTimeout(this.b.tick.bind(this.b), interval);
    }
}
class B {
    constructor(name){
        this.name = name;
        this.ele = window.document.getElementById('B');
    }
    tick() {
        console.log(this);
        this.ele.innerText += ' ' + this.name;
    }
}

Which bound A.b to this within B.tick and worked.

Here's a fiddle with bind: https://jsfiddle.net/jrme9hyh/

And one without bind which fails: https://jsfiddle.net/2jde8tq3/

查看更多
劳资没心,怎么记你
3楼-- · 2020-01-24 21:51

Have you tried;

window.setTimeout("myObject.run" ,(1000 * randomNumber(1,5)));
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-01-24 21:54

Shorter way. Without anonymous func.

    var self = this;
    setTimeout(self.method, 1000);
查看更多
唯我独甜
5楼-- · 2020-01-24 22:02

you can just use the arrow function syntax:

setTimeout(() => {
     this.doStuff();
 }, 4000);
查看更多
forever°为你锁心
6楼-- · 2020-01-24 22:03

You can also bind a function to scope.

setTimeout(this.run.bind(this) ,(1000 * randomNumber(1,5)));

Be warned Function.prototype.bind is ES5

查看更多
劫难
7楼-- · 2020-01-24 22:04
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

inside func, this always refer to the global object. you can pass in the current object into func,

var timeoutID = window.setTimeout(func, delay, this);
function func(that) {...}

unfortunately it does NOT work in IE

Note that passing additional parameters to the function in the first syntax does not work in Internet Explorer.

查看更多
登录 后发表回答