This is a very common mistake in Javascript. I think everyone including me did this at one point. It is fairly easy to understand, though.
What's going on
When you call a function as a method of an object, you set its context to the object. That means that this inside this function will point to your context object.
MyObject = {};
MyObject.someValue = 1;
MyObject.myMethod = function() {
console.log(this.someValue); // This will log "1" to the console, as expected
};
Now comes the tricky part: You can change the context of a function. Let's add some more lines of code here:
MyOtherObject = {};
MyOtherObject.someValue = 2;
MyOtherObject.myMethod = MyObject.myMethod;
When you now call MyOtherObject.myMethod you call the same function as if you would call MyObject.myMethod, but in one case this points to MyObject and in the other case it points to MyOtherObject.
Now, when you call setInterval(MyObject.myMethod, 1000), the functions context will be set to window (technically, setInterval calls window.setInterval) and since window does not have a property called someValue, it will just be undefined.
How to fix it
To fix this, you can create another reference to your LoginScreen object. It will always point to the same object inside the entire scope, unless you change it. You can then use it as an alternative to this without worrying about the context.
function LoginScreen() {
this.IntervalID = null;
this.counter = 0;
// Create another reference to "this"
var self = this;
this.Start = function () {
// The function behind "this.Update" will always be called with "window"
// as its context.
this.IntervalID = window.setInterval(this.Update, 60 / 1000);
};
this.Stop = function () {
// This function is called as "self.Stop", therefore "this" points to
// "self", which points to the right object, so you can use "this".
clearInterval(this.IntervalID);
};
this.Update = function () {
// Inside this function, "this" points to "window".
// You therefore have to use the previously declared "self"
// to point to the right object.
self.counter++;
alert(self.counter);
if (self.counter > 5) self.Stop();
};
}
LS = new LoginScreen();
LS.Start();
Further reference
this - Mozilla Developer Network Another explanation of the beviour of this in JavaScript, along with some functions to control it.
setInterval()parameter.