-1

The Problem

I have created a constructor called Game. Then, I tried to expand it's functionality by adding two new functions (update and render) using prototype.

However, I'd like my update function to be able to call both itself and then call render.

My Code

var Game = function(){

};

Game.prototype.update = function(){
    requestAnimationFrame(this.render);
    requestAnimationFrame(this.update);
};
Game.prototype.render = function(){
  console.log('Rendering');
};

var game = new Game();
game.update();

What I have also Tried

requestAnimationFrame(render);
requestAnimationFrame(update);

And..

requestAnimationFrame(Game.render);
requestAnimationFrame(Game.update);

And...

requestAnimationFrame(Parent.render);
requestAnimationFrame(Parent.update);

But due to some (glaringly obvious) gaps in my javascript knowledge, I can't make this work. It appears as if this and parent are both referring to window - I'm guessing that's because of how the functions were created.

This is the error I receive;

Game.js:6 Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function.

Questions I've already found

I've already found the following questions on SO, but they don't appear to be all that helpful to this particular problem.

Javascript multiple prototype functions - how to call one from another

calling function from prototype function

Community
  • 1
  • 1
Lewis
  • 3,479
  • 25
  • 40
  • I thought about trying that, but I couldn't work out where to place it. Would the definition of self be in the constructor, and the call in the prototype? – Lewis Apr 05 '16 at 11:05
  • @Rajesh I still wondering why you use a variable for storing `this` reference. That is completely unnecessary. https://jsfiddle.net/pberkxt9/ – Rajaprabhu Aravindasamy Apr 05 '16 at 11:13
  • @RajaprabhuAravindasamy check the [Updated Fiddle](https://jsfiddle.net/pberkxt9/1/). I tried my assumption, but even that is not working. – Rajesh Apr 05 '16 at 11:15
  • 1
    @downvoters - Comments welcome. – Lewis Apr 05 '16 at 11:17
  • @Rajesh Oh.. for a recursive call it is required. – Rajaprabhu Aravindasamy Apr 05 '16 at 11:17
  • Yes. But question is, if I'm storing reference in `self`, why is `self` pointing to window? I mean, if I'm calling `self.update`, this should point to `self`, or we are just passing function and since it is invoked later, this will point to window. – Rajesh Apr 05 '16 at 11:18
  • @Rajesh It looks like it's the same problem as my original post - as `self` is defined in the prototype function, `self` is redefined to `this` on the second recursion (and on the second recursion, `this` is pointing to window) – Lewis Apr 05 '16 at 11:20
  • @Lewis so I guess, link previously shared explains issue correctly. – Rajesh Apr 05 '16 at 11:23

2 Answers2

3

Those lines

requestAnimationFrame(this.render);
requestAnimationFrame(this.update);

should be

requestAnimationFrame(this.render.bind(this));
requestAnimationFrame(this.update.bind(this));

Otherwise, in the second execution of your recursion, keyword this will refer to window object instead of Game. And window.update is obviously not a function, as the error specified.

Lewis
  • 14,132
  • 12
  • 66
  • 87
  • Interesting, thank you - I wonder why the reference to this is destroyed after the `first run` - it seems counter-intuitive. What would I look up for more information about this? – Lewis Apr 05 '16 at 11:12
  • This might help: http://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback – Rajesh Apr 05 '16 at 11:13
1

You have lost the reference to the Game object, try binding 'this' like so:

var Game = function(){

};

Game.prototype.update = function(){
    requestAnimationFrame(this.render.bind(this));
    requestAnimationFrame(this.update.bind(this));
};
Game.prototype.render = function(){
  console.log('Rendering');
};

var game = new Game();
game.update();
Matt
  • 4,107
  • 3
  • 29
  • 38