使用“this”在 JavaScript 类中使用 setTimeout()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5911211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:28:22  来源:igfitidea点击:

setTimeout() inside JavaScript Class using "this"

javascriptoopclosures

提问by Dean

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: thisreferences 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?

我正在尝试setTimeout()在 JavaScript 中的类函数中使用。本setTimeout()应该引发在同一类的另一种方法,所以我向它传递函数写成window.setTimeout("this.anotherMethod", 4000)。这带来了问题:this引用调用对象,在setTimeout()它的情况下是window. 如何使用附件返回对类对象本身的引用?

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();
    }
}

}

}

回答by Tikhon Jelvis

You can do this:

你可以这样做:

 var that = this;
 setTimeout(function () {
     that.doStuff();
 }, 4000);

You can also bindfor more succinct code (as originally pointed out by @Raynos):

您还可以bind使用更简洁的代码(正如@Raynos 最初指出的那样):

setTimeout(this.doStuff.bind(this), 4000);

bindis a standard library function for exactly this coding pattern (ie capturing thislexically).

bind是正是这种编码模式(即按this词法捕获)的标准库函数。

回答by Raynos

You can also bind a function to scope.

您还可以将函数绑定到作用域。

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

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

Be warned Function.prototype.bindis ES5

注意Function.prototype.bind是 ES5

回答by GordonM

thiscan be problematic in javascript, as you've discovered.

this正如您所发现的,在 javascript 中可能有问题。

I usually work around this by aliasing thisinside the object so that I can use the alias whenever I need a reference back to the containing object.

我通常通过this在对象内部设置别名来解决这个问题,这样我就可以在需要引用回包含对象时使用别名。

MyObject = function ()
{
    var self = this;

    // The rest of the code goes here

    self.wait = function(){
        window.setTimeout(self.run ,(1000 * randomNumber(1,5)));
    }
}

回答by Gijs

this.wait = function(){
    var self = this;
    window.setTimeout(function() { self.run() } ,(1000 * randomNumber(1,5)));
}

So you store the reference to the object you're calling .run on in a local variable ('self').

因此,您将调用 .run 的对象的引用存储在局部变量 ('self') 中。

回答by Quentin

thisis sensitive to the context in which it is called. When you pass a string to setTimeoutthen that is evaled in a completely different context.

this对调用它的上下文敏感。当您将字符串传递给setTimeoutthen 时,它会eval在完全不同的上下文中进行。

You need to preserve the current value of this(by copying it to a different variable) and maintain the scope (by not using (implied) eval).

您需要保留的当前值this(通过将其复制到不同的变量)并维护范围(通过不使用 (implied) eval)。

this.wait = function(){
    var self = this;
    setTimeout(function () { self.run() },
              (1000 * randomNumber(1,5))
              );
}

回答by Alnitak

At the top of your main myObjectmake a new reference to the current value of this:

在 main 的顶部myObject对 的当前值进行新的引用this

var self = this;

and then create a closure for your timer callback that uses that new reference instead of the global object that setTimeoutwill use as the default context in callbacks:

然后为您的计时器回调创建一个闭包,该闭包使用该新引用而不是setTimeout将用作回调中默认上下文的全局对象:

setTimeout(function() {
    self.run();
}, 4000);

回答by nandin

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

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

inside functhis始终引用全局对象。您可以将当前对象传入func,

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

unfortunately it does NOT work in IE

不幸的是它在 IE 中不起作用

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

请注意,将附加参数传递给第一种语法中的函数在 Internet Explorer 中不起作用。

回答by BusterLuke

Have you tried;

你有没有尝试过;

window.setTimeout("myObject.run" ,(1000 * randomNumber(1,5)));

回答by Mioe Galaxy

you can just use the arrow function syntax:

你可以只使用箭头函数语法:

setTimeout(() => {
     this.doStuff();
 }, 4000);

回答by M Ahmed Mushtaq

class A{

   setTimeout(()=>{

       // here this != undefined because of arrow function

  },500);

}