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();
}
}
}
At the top of your main
myObject
make a new reference to the current value ofthis
:and then create a closure for your timer callback that uses that new reference instead of the global object that
setTimeout
will use as the default context in callbacks:You can use this code instead, which works in all modern browsers -
Ref: http://klevo.sk/javascript/javascripts-settimeout-and-how-to-use-it-with-your-methods/
It is not recommended to use setTimeout or setInterval using strings
this
is sensitive to the context in which it is called. When you pass a string tosetTimeout
then that iseval
ed in a completely different context.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
).You can do this:
You can also
bind
for more succinct code (as originally pointed out by @Raynos):bind
is a standard library function for exactly this coding pattern (ie capturingthis
lexically).So you store the reference to the object you're calling .run on in a local variable ('self').