I am a proficient c# programmer, and I have a little bit of experience with HTML and Javascript, but I can't seem to figure out objects.
I am attempting to create a loop, which just keeps updating until the counter reaches 5 then stops the loop. but in the Update method counter = NaN.
This is my exact code.
function LoginScreen() {
this.IntervalID = null;
this.counter = 0;
this.Start = function () {
this.IntervalID = setInterval(this.Update, 60 / 1000);
};
this.Stop = function () {
clearInterval(this.IntervalID);
};
this.Update = function () {
this.counter++;
alert(this.counter);
if (this.counter > 5) this.Stop();
};
}
LS = new LoginScreen();
LS.Start();
The problem is scope of the inner this
of your Start()
, Stop()
and Update()
functions. Within those functions, this
is referring to the function, and not your LoginScreen
object.
To get around these problems, I like to use a little self
variable to help with scope issues. That way, whatever is referring to the self
variable will use the object. Here's what I mean:
function LoginScreen() {
// add this for scope fun...
var self = this;
this.IntervalID = null;
this.counter = 0;
this.Start = function () {
self.IntervalID = setInterval(self.Update, 60 / 1000); // updated...
};
this.Stop = function () {
clearInterval(self.IntervalID); // updated...
};
this.Update = function () {
self.counter++; // updated...
alert(self.counter); // updated...
if (self.counter > 5) self.Stop(); // updated...
};
}
LS = new LoginScreen();
LS.Start();
Hope this makes sense!
You ran into the dreaded Javascript "this" problem.
Try changing your this.Update code to:
var self = this;
this.Update = function () {
self.counter++;
alert(self.counter);
if (self.counter > 5) self.Stop();
};
But wait there is more
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.
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.
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();
this - Mozilla Developer Network Another explanation of the beviour of this in JavaScript, along with some functions to control it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.