Skip to main content
GameDev.net gamedev.net
🔒 Locked

Newbie Javascript question

Started by jdub May 18, 2013 at 7:31 AM 3 replies 1.9k views
Original Post
jdub
jdub

So I have this javascript code:


var sim = new function()
{
...
...
...
this.Tick = function () 
	{
		var currTime = Date.now();
		var elapsedMS = currTime - this.lastUpdateTime;

		this.Update(elapsedMS);
		this.Render();

		this.lastUpdateTime = currTime;
	};

this.Run = function()
	{
		this.tickIntervalId = setInterval(this.Tick, 1000/60); //Update at 60 fps
	};

Getting the following error: Uncaught ReferenceError: Update is not defined.

Anybody know what's causing this?

J.W.
Neophyte
Neophyte

The problem is right there in the error message: You are calling


this.Update(elapsedMS);

in your this.Tick function, but you have not defined an Update function anywhere.

jdub
jdub

Oops. I realized that I only posted part of the code I have. Here is more relevant code:


//create singleton class
var sim = new function()
{
...
this.Run = function()
	{
		this.tickIntervalId = setInterval(this.Tick, 1000/60); //Update at 60 fps
	};
...

this.Update = function (elapsedMS) {
		
	  for (var i = 0; i < nodeArr.length; i++) {
		nodeArr.Update();
	  }
	};
...
this.Tick = function () 
	{
		var currTime = Date.now();
		var elapsedMS = currTime - this.lastUpdateTime;

		this.Update(elapsedMS);
		this.Render();

		this.lastUpdateTime = currTime;
	};
};

sim.Run();
J.W.
lietu
lietu

In JavaScript functions don't really have a "context" associated statically with them, it is evaluated dynamically .. setTimeout and setInterval basically "reset" the context and your call to "this.Tick" doesn't know what "this" is.

Change

this.tickIntervalId = setInterval(this.Tick, 1000/60); //Update at 60 fps
To
this.tickIntervalId = setInterval(function() { this.Tick() }, 1000/60); //Update at 60 fps

To not lose the context
Edit: missing parenthesis on "To" -line's call to Tick()
Another edit:
Actually, not 100% sure of the "this.Tick()" inside that function either, the only sure-fire way to not lose "this" is to define something like var me = this; on the line above and call me.Tick() instead.
I.e.:
var me = this;
this.tickIntervalId = setInterval(function() { me.Tick() }, 1000/ 60);
Concentrate
Concentrate

If you are running on chrome, you can simply use the bind function,


this.tickIntervalId = setInterval(this.Tick.bind(this), 1000/60); //Update at 60 fps

or if you are using the popular underscore utility


this.tickIntervalId = setInterval(_.bind(this.Tick,this), 1000/60); //Update at 60 fps

The problem is that your Tick function gets called in a global context. Which means that, the 'this' pointer is the global 'this' which is not what you need. Hence you need to bind the 'this' context so that when the Tick function gets called from a global context, the original 'this' pointer is still saved.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.