Sterling
Sterling

Reputation: 4213

Javascript event listener

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

Answers (2)

suddjian
suddjian

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

ibrahim mahrir
ibrahim mahrir

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

Related Questions