1

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?

2
  • Where is your Player class? Commented Feb 15, 2017 at 23:47
  • The Player class is outside of the Pong class, but in the same file. I'll edit my question to show that. Commented Feb 16, 2017 at 1:02

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

it's not this, it's pong
@ChemicalRocketeer yeah I just noticed! I thought main was inside the class Pong!
1

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.

2 Comments

you can also canvas.addEventListener('mousemove', function(e) { pong.handleMouseMove(e); }) - not as nice, but very common
I see...I appreciate the explanation. I accepted the other answer because it was closer to the top (and fixed by the time I saw it). Thanks!!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.