This has nothing to do with requestAnimationFrame
. It is a basic JavaScript issue related to passing functions in general, and the meaning of this
.
People tend to think that a function-valued property inside an object, such as myFn
in the below
var myObj = {
myFn: function() {console.log(this);}
};
somehow has myObj
"baked in" as this
. Wrong. this
is assigned only at the time the function is called. If I say myObj.myFn()
, this
becomes myObj
, but I could just as easily say myObj.myFn.call(otherObj)
to have this
be something else.
This becomes important when passing functions around as parameters to setTimeout
, promises, or requestAnimationFrame
. Just passing myObj.myFn
passes the function, but it has no associated this
. requestAnimationFrame
has no idea where this function came from and what this
to call it with, so it calls it with a this
of window
, or null
, or 0, or undefined
, or who knows what. This causes the error.
The simplest way to fix the problem is to simply say
requestAnimationFrame(function() {av.update(); });
Now update
is called with the correct this
.
A more sophisticated, equivalent way, would be
requestAnimationFrame(av.update.bind(av));
Other note
I don't think the way you're passing the function itself to requestAnimationFrame
is going to work well. You're essentially setting up a chain of recursive calls, and eventually the stack will overflow. You need to separate the logic to be executed on the requestAnimationFrame
callback from the logic to request the frame.