My question is related to the following:
setTimeout() inside JavaScript Class using “this”
calling a function inside setTimeout and inside a function
I'm trying to implement a simple animation loop. The draw function is a member function of a state object. I'm having problems getting 'this' to work within the setTimeout and requestAnimationFrame.
I have the following code:
ANIM.State.prototype = {
constructor: ANIM.State,
play: function(){
if(!this.paused){
var that = this;
setTimeout(function(){
requestAnimationFrame(that.play);
that.setFrameNum(that.currentFrame + 1); //draw code is in here
}, 1000 / 24);
}
}
};
However, when I call play(), it runs twice and stops.
Is there a better way to do this? I'd really like to keep this function as a class function, and not a global one, if possible.
You can solve your issue with
.bind()
like this:The problem is all that is passed to
requestAnimationFrame()
is a reference to the.play
method and it is then executed as a normal function call sothis
inside it will be wrong and will not point to your object. This is a common problem when passing a method as a callback where you want it to be called asobj.method()
.There are numerous possible work-arounds, but the easiest in modern browsers is to use
.bind()
as I've shown above. This actually creates a small stub function that then callsthat.play()
rather than justplay()
so that the object reference is used as you need and it's that stub function that is passed torequestAnimationFrame()
.You could also do it like this (creating your own stub function), though
.bind()
seems cleaner to me: