JavaScript 类中的 setTimeout() 使用“this”
Posted
技术标签:
【中文标题】JavaScript 类中的 setTimeout() 使用“this”【英文标题】:setTimeout() inside JavaScript Class using "this" 【发布时间】:2011-08-20 03:39:44 【问题描述】:我正在尝试在 javascript 的类函数中使用 setTimeout()
。 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();
【问题讨论】:
我设置了 = this,并将其用于所有方法,就像魔术一样,为所有回答这个问题的人 +1,非常感谢。 【参考方案1】:你可以这样做:
var that = this;
setTimeout(function ()
that.doStuff();
, 4000);
您也可以bind
获取更简洁的代码(正如@Raynos 最初指出的那样):
setTimeout(this.doStuff.bind(this), 4000);
bind
是针对这种编码模式的标准库函数(即从词法上捕获this
)。
【讨论】:
@David Dorward:我在点击提交后才意识到这一点。我不应该在早上 5 点发帖。 @Dorward 在编辑答案之前发表了评论。现在是正确的 我一直被困在这个问题上,这似乎解决了我的问题。谢谢。 我在一个实现了单例模式的类中使用了这个答案,它可以工作! @Antoine:很公平,而且 ES5 支持现在可能已经足够广泛,使用它完全不是问题。我将对此进行编辑。【参考方案2】:您还可以将函数绑定到范围。
setTimeout(this.run.bind(this) ,(1000 * randomNumber(1,5)));
警告Function.prototype.bind
是 ES5
【讨论】:
你可以绑定到任何 js 项目上工作:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… :)【参考方案3】:this
在 javascript 中可能会出现问题,正如您所发现的那样。
我通常通过在对象内部给this
加上别名来解决这个问题,这样当我需要引用回包含对象时就可以使用别名。
MyObject = function ()
var self = this;
// The rest of the code goes here
self.wait = function()
window.setTimeout(self.run ,(1000 * randomNumber(1,5)));
【讨论】:
我发现self
是一个最容易引起误解的标识符,尤其是因为它与 this
具有非常相似的含义,正如您所指出的,这意味着其他东西。
这只是一个示例,您可以将其称为 MyObjRef,或者您认为应该使用的任何其他名称。关键是它为您提供了一种获取对象引用的方法。【参考方案4】:
class A
setTimeout(()=>
// here this != undefined because of arrow function
,500);
【讨论】:
在回答一个老问题时,如果您包含一些上下文来解释您的答案如何提供帮助,那么您的答案将对其他 *** 用户更有用,特别是对于已经有一个已接受答案的问题。请参阅:How do I write a good answer。【参考方案5】:this.wait = function()
var self = this;
window.setTimeout(function() self.run() ,(1000 * randomNumber(1,5)));
因此,您将对正在调用 .run 的对象的引用存储在局部变量(“self”)中。
【讨论】:
【参考方案6】:this
对调用它的上下文很敏感。当您将字符串传递给 setTimeout
时,那是 eval
ed 在完全不同的上下文中。
您需要保留this
的当前值(通过将其复制到不同的变量)并保持范围(通过不使用(隐含)eval
)。
this.wait = function()
var self = this;
setTimeout(function () self.run() ,
(1000 * randomNumber(1,5))
);
【讨论】:
【参考方案7】:在主 myObject
的顶部,对 this
的当前值进行新的引用:
var self = this;
然后为您的计时器回调创建一个闭包,该闭包使用该新引用而不是 setTimeout
将用作回调中的默认上下文的全局对象:
setTimeout(function()
self.run();
, 4000);
【讨论】:
【参考方案8】:var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
在func
内部,this
始终引用全局对象。可以将当前对象传入func,
var timeoutID = window.setTimeout(func, delay, this);
function func(that) ...
不幸的是,它在 IE 中不起作用
Note that passing additional parameters to the function in the first syntax does not work in Internet Explorer.
【讨论】:
【参考方案9】:你可以只使用箭头函数语法:
setTimeout(() =>
this.doStuff();
, 4000);
【讨论】:
【参考方案10】:你试过了吗;
window.setTimeout("myObject.run" ,(1000 * randomNumber(1,5)));
【讨论】:
【参考方案11】:您可以改用此代码,它适用于所有现代浏览器 -
setTimeout(function(thisObj) thisObj.run();,1000,this);
参考:http://klevo.sk/javascript/javascripts-settimeout-and-how-to-use-it-with-your-methods/
【讨论】:
【参考方案12】:更短的方式。没有匿名函数。
var self = this;
setTimeout(self.method, 1000);
【讨论】:
【参考方案13】:不建议使用字符串使用 setTimeout 或 setInterval
setTimeout("myFunction()", 5000);
//this is the same as
setTimeout(function() eval("myFunction()"); , 5000)); //<-- eval == BAD
【讨论】:
【参考方案14】:遇到了一个更复杂的情况...A类有一个B类型的成员和一个调用setTimeout的方法,该方法调用B类的一个方法。解决如下:
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;
在 B.tick 中将 A.b 绑定到 this 并起作用。
这是bind
:https://jsfiddle.net/jrme9hyh/的小提琴
还有一个没有bind
的失败:https://jsfiddle.net/2jde8tq3/
【讨论】:
以上是关于JavaScript 类中的 setTimeout() 使用“this”的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript:在另一个 setTimeOut(嵌套 setTimeOut)中的 setTimeOut 以刺激 API 响应不起作用
在javascript中的另一个setTimeout函数中使用setTimeout
JavaScript 的setTimeout 和Angular中的$timeout的區別