Reputation: 4213
I'm trying to make a simple Pong game in Javascript. I have a Pong class, and I'd like to create a method to move the player rectangles based on how the mouse moves:
class Player
{
constructor()
{
// do stuff
}
}
class Pong
{
constructor(canvas)
{
//do stuff
this.player1 = new Player(true); // Create an instance of another class
}
handleMouseMove(event)
{
var y = event.clientY;
// this.player1 is undefined!!
console.log("this.player1: "+this.player1);
this.player1.pos.y = y;
}
function main()
{
// Initialize canvas and context
canvas = document.getElementById('mycanvas');
const pong = new Pong(canvas);
canvas.addEventListener('mousemove', pong.handleMouseMove);
}
Whenever I start moving the mouse, it tells me that player1 is undefined. How can I set the class method as the event listener and have it know about the class' members?
Upvotes: 1
Views: 268
Reputation: 2396
This is one of the worst parts of javascript, in my opinion. When you pass pong.handleMouseMove
to addEventListener
, you are passing the function itself. In that context, when the event fires, it is calling the function outside the context of your Pong
instance. You need to call bind on handleMouseMove
, like so:
canvas.addEventListener('mousemove', pong.handleMouseMove.bind(pong));
bind
exists on all functions, and returns a new function which you can pass around, and ensures that this
inside the function is bound to the specified parameter (in this case, pong
).
edit: The other answer by ibrahim mahrir is wrong, you have to pass your pong
instance to the bind
function. Whatever you pass is what this
will be assigned to inside the function you are binding.
Upvotes: 1
Reputation: 31682
It's because this
inside the event listener refer the the element that fired the event (the canvas). You can bind the this
keyword using bind like this:
canvas.addEventListener('mousemove', pong.handleMouseMove.bind(pong));
// ^^^^^^^^^^^
bind
will return a function that its this
keyword set to whatever you gave it as parameter.
Upvotes: 3