0

I've got this strange behavior and even if I can easily workaround it I'd like to know why this happens.

    function Game () {
        this.viewport = { ... };
        this.player = Player;
        this.renderer = { ... };
        this.stage = { ... };

        this.init = function () {                 
             //THIS GETS EXECUTED
             this.setKeyBindings();
        }

        this.run = function () {
             //THIS WORKS TOO
             requestAnimFrame(this.update);
        }

        this.update = function () {
             //BAD! THROWS UNDEFINED IS NOT A FUNCTION
             //HERE I NEED TO USE A REFERENCE HERE

             this.processInput();
             this.renderer.render(this.stage);
             this.handleLogic();

             //EVEN THIS ONE WON'T WORK, BUT IT WORKED IN init()!
             requestAnimFrame(this.update);
        };

        //METHODS ARE DEFINED THE SAME WAY
        this.processInput = function () {
            ...
        };

        this.handleLogic = function () {
            ...
        };

        this.setKeyBinding = function () {
            ...
        }
    }       

So I'm clearly missing something:

this.setKeybindings() gets successfully executed from within the init method.

this.processInput() throws an error.

I don't need a workaround, i solved it by using a local reference, like this:

        function Game () {
         var reference = this;
         .......
         this.update = function () {
             //NOW WORKS
             reference.processInput();
             reference.handleLogic();
             reference.renderer.render(reference.stage);
             requestAnimFrame(reference.update);
        }

        this.init = function () {
             //THIS ONE WORKS EVEN USING 'this'
             this.setKeyBindings()
        }
    }

I'd like to know why 'this' works only in some methods (like init) while it doesn't in others (like update).

vinzdef
  • 1,717
  • 2
  • 12
  • 22
  • 1
    I'm pretty sure `this.handleLogic()` does not work. Called from `requestAnimFrame`, the `this` value of the invocation is probably `window`; do you have a global `handleLogic` function? – Bergi Nov 11 '14 at 14:01
  • Sorry, i have made an error. Like you said it doesn't work. However I have another method which does work with the 'this' keyword. I'll update the question. Can you elaborate on why 'this' doesn't work? – vinzdef Nov 11 '14 at 15:01
  • I think I got what you mean, when called from within requestAnimFrame the context of the update function is global so 'this' refers to window and not to the class it gets defined in. If that's correct, is using a reference the only/best way to do so? – vinzdef Nov 11 '14 at 15:24
  • 1
    Yes - or use `bind`. For details, see the [canonical question](http://stackoverflow.com/q/20279484/1048572) - I wonder whether I should close as a duplicate. – Bergi Nov 11 '14 at 18:33
  • That answer cleared every doubt I had about it, so I agree on marking __this__ one as duplicate. Thank you for the link! – vinzdef Nov 12 '14 at 00:35

1 Answers1

0

declare local variable and assign this to it and use it everywhere:

function Game () {
     var me = this;
     .......
     me.update = function () {
         me.processInput();

         me.handleLogic();

         me.renderer.render(me.stage);

         requestAnimFrame(me.update);
    }
}

this will solve your problems with references

  • Thank you for the reply. Already did this (as explained in the question) with the only difference that I used a property rather than a local variable. I was asking for a more elegant solution or a "better"/"standard" way to do so, like a pattern to apply or a different approach to the problem. It's common pratice to declare a reference variable inside the constructor for this purpose? Does anyone do this way? – vinzdef Nov 11 '14 at 14:57