4

I am trying to pass a function to an object through the constructor in order to use it inside the class using bind. Here is my code.

gameManager.js

    var GameManager = function() {

        this.inputManager = new InputManager(   this.moveRight.bind(this), this.moveDown.bind(this),
                                            this.moveLeft.bind(this), this.moveUp.bind(this));
    }

GameManager.prototype.moveLeft = function () {
    ...
}

inputManager.js

var InputManager = function(moveRight, moveDown, moveLeft, moveUp) {

    this.moveRight = moveRight
    this.moveDown = moveDown
    this.moveLeft = moveLeft
    this.moveUp = moveUp
}

then I want to be able to call one of the "move" functions in InputManager

InputManager.prototype.doKeyDown = function (e) {

    if ( (e.keyCode === 65) || (e.keyCode === 37)) { //A, left arrow
     console.log(this.moveLeft)   
     this.moveLeft()
    }
}

But I am getting the following error: Uncaught TypeError: this.moveLeft is not a function. When printing I get undefined. What am I doing wrong, or is there another way of doing this?

Pierre
  • 1,114
  • 2
  • 10
  • 24
  • Shouldn't `GameManager.prototype.moveRight` include `moveLeft` and not `moveRight`? – james Jul 06 '16 at 15:45
  • Sorry, I have just posted one of them, they look similar though – Pierre Jul 06 '16 at 15:46
  • Cannot reproduce: https://jsfiddle.net/k9rh211z/ What's different? – user3297291 Jul 06 '16 at 15:47
  • So what is it? Can you log the value of `this.moveLeft` to the console to see what it _actually_ is? – somethinghere Jul 06 '16 at 15:48
  • Also, can you provide us more context of _where_ you are calling the `this.moveLeft` function? – somethinghere Jul 06 '16 at 15:52
  • When you call `this.moveLeft` in `InputManager`, what do you want it to use as the context for `this`? – Dan Prince Jul 06 '16 at 15:54
  • @somethinghere Updated my question. @ user3297291 I cant tell the difference :/ – Pierre Jul 06 '16 at 15:55
  • If you're attaching your method as an event listener, there might be an additional `bind` going on behind the scenes (depending on how you set it up). jQuery for example binds the `element` to `this` when setting up an event listener. You can make sure the `this` context is correct by using another `.bind(instance)` when you add the event method. – user3297291 Jul 06 '16 at 15:57
  • @Pierre It's a bit flummoxing, it all looks like it should at least work (it might throw different errors, but not `this thing is undefined`). I am wondering, though, if this duplication is useful. Why not do something like `function InputManager(forObject){ this.parent = forObject; }` and then call them using `this.forObject.moveLeft()`? – somethinghere Jul 06 '16 at 15:58
  • Yes it seems like its something else, thanks for the help, much appreciated. – Pierre Jul 06 '16 at 16:16
  • Binding your `GameManager` methods is fine when you pass them to the input manager, but that's nothing to do with your problem. You will also need to bind your `InputManager` methods when you use them as event listeners - the problem is how `doKeyDown` is called. – Bergi Jul 06 '16 at 17:01

0 Answers0