Using a class method as function for "Update" or "Draw"
Closed this issue · 2 comments
Hello !
I'm having a problem with the Update function.
Let's say I have a class named "Game" which has a method named "update"
Normally, I could do this :
let game = new Game();
game.update();
and the method could be like this :
update() {
this.objects.doStuff();
}
But when I try to call the method with the Update call, I can't access "this"
I get the following error : this is undefined
Is it due to the plugin implementation or is this simple javascript behaviour that I'm not aware of ?
Thank you very much.
Ok I found the solution myself by looking at #18
MainLoop.setUpdate(delta => {game.update();});
instead of
MainLoop.setUpdate(game.update);
I don't really get it but I think it might be related to the call with parenthesis ?
Just to be clear what's happening, if you have an ES6 class like this:
class MyClass {
method1() { console.log(this); }
method2 = () => { console.log(this); }
}
Functions written as methods or using the function
keyword have their own this
context, whereas arrow functions use the surrounding this
context. So:
const mc = new MyClass();
const m1 = mc.method1;
m1(); // prints `undefined` because the method is called without the `mc` context
mc.method1(); // prints mc
const m2 = mc.method2;
m2(); // prints mc because the `this` context was captured where `method2` is declared
mc.method2(); // prints mc
So if you want method1
(in this example) to run outside of its class with a specific this
, you need to explicitly bind it:
const mc = new MyClass();
const m1 = mc.method1.bind(mc);
m1(); // prints mc
Applying this to your case, you could either wrap your update function as you discovered:
MainLoop.setUpdate(delta => game.update(delta));
or you could bind it:
MainLoop.setUpdate(game.update.bind(game));
or you could change how your method is declared in the first place.