1

I have a class object that handles some movement for an object. In the mouseMove all the variables need to be a self even the static values like paddleWidth but in the movement function the this key word worked for the static values of paddleWidth. Could someone help me understand how to know when self should be used instead of this?

export class Paddle {
constructor (world) {
    var self = this;
    this.canvas = world.canvas;
    this.ctx = world.ctx;
    this.paddleHeight = 10;
    this.paddleWidth = 75;
    this.paddleX = (this.canvas.width - this.paddleWidth) / 2; // location
    this.rightPressed = false;
    this.leftPressed = false;
    this.keyDownHandler= function(e) {
        if (e.keyCode == 39) {
            self.rightPressed = true;
        }
        else if (e.keyCode == 37) {
            self.leftPressed = true;

        }
    };

    this.keyDown = document.addEventListener("keydown", this.keyDownHandler, false);

    this.keyUpHandler= function(e) {
        if (e.keyCode == 39) {
            self.rightPressed = false;
        }
        else if (e.keyCode == 37) {
            self.leftPressed = false;

        }
    };

    this.keyUp = document.addEventListener("keyup", this.keyUpHandler, false);

    this.mouseMoveHandler = function(e) {
        console.log('mouseMove', this.paddleX)
        var relativeX = e.clientX - self.canvas.offsetLeft;
        if(relativeX > 0 && relativeX < self.canvas.width){
            self.paddleX = relativeX - self.paddleWidth/2
        }
    };

    this.mouseMove = document.addEventListener("mousemove", this.mouseMoveHandler, false);

    this.movement= function() {
        console.log('movement', this.paddleX)
        if (this.rightPressed && this.paddleX < this.canvas.width - this.paddleWidth) {
            self.paddleX += 7;
        } else if (this.leftPressed && this.paddleX > 0) {
            self.paddleX -= 7;
        }
    };
  }
Wolf_Tru
  • 523
  • 7
  • 19
  • 2
    Use anonymous arrow functions instead and use `this` everywhere, never use `self`. eg `.addEventListener("keydown", () => this.keyDownHandler())`. Also consider using methods in your class instead of assigning them in the constructor – CertainPerformance Oct 16 '18 at 01:23
  • @CertainPerformance, you can't always avoid the use of `self` though. The `movement` function requires the function to use a `this` relative to the function rather than the class but then `self` is required to access the class properties. I do completely agree that in all cases, where possible, the use of `self` should be avoided. – Simon K Oct 16 '18 at 01:28
  • @SimonK I don't think it's needed. We don't see where `movement` is invoked, but it's probably meant to be invoked with a context of the instantiated object, in which case using `this` everywhere will work just fine. OP is using both `self` and `this` in the function, but replacing all `self`s with `this` should work. If some function *did* need access to both `this` and another instantiated object, that other object should be passed as a parameter, rather than using `.call` or something to alter the calling context. – CertainPerformance Oct 16 '18 at 01:33
  • @CertainPerformance thanks for the tip, ill give it a try. do i have to turn my declared functions or key up and down handlers into arrow functions too or just the call backs like your example? `.addEventListener("keydown", () => this.keyDownHandler())`? – Wolf_Tru Oct 16 '18 at 01:57
  • Only the callbacks need it. Still, your other functions *should* be methods on the `Class` rather than being declared in the constructor. – CertainPerformance Oct 16 '18 at 01:58
  • @CertainPerformance I did it but getting a reference error now. could you check my gist to see what I did wrong? https://gist.github.com/wolffles/0aeb0ba08342917243746b5880731f95 – Wolf_Tru Oct 16 '18 at 02:11
  • A reference error where? What's the error? – CertainPerformance Oct 16 '18 at 02:14
  • oh no its undefined, its cuz i changed something. the code the gist link returns undefined for the variable e.clientX `TypeError: undefined is not an object (evaluating 'e.clientX')` – Wolf_Tru Oct 16 '18 at 02:15
  • 1
    If you need the event, use it and pass it in the handler arrow function. `(e) => this.keyDownHandler(e)` – CertainPerformance Oct 16 '18 at 02:24
  • oh wow silly mistake, thanks! its working like a charm! truly appreciate your help! :D – Wolf_Tru Oct 16 '18 at 02:27

0 Answers0