0

我是一名熟练的 c# 程序员,我对 HTML 和 Javascript 有一点经验,但我似乎无法弄清楚对象。

我正在尝试创建一个循环,它只会不断更新,直到计数器达到 5 然后停止循环。但在更新方法计数器 = NaN。

这是我的确切代码。

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();
4

3 回答 3

3

问题是this你的Start(),Stop()Update()函数内部的范围。在这些函数中,this指的是函数,而不是您的LoginScreen对象。

为了解决这些问题,我喜欢使用一个小self变量来帮助解决范围问题。这样,任何引用self变量的东西都将使用该对象。这就是我的意思:

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();

希望这是有道理的!

于 2013-10-16T09:08:55.030 回答
2

您遇到了可怕的 Javascript“this”问题。

尝试将您的 this.Update 代码更改为:

var self = this;
this.Update = function () {

        self.counter++;
        alert(self.counter);

        if (self.counter > 5) self.Stop();
    };

但是等等还有更多

于 2013-10-16T09:10:13.033 回答
2

这是 Javascript 中一个非常常见的错误。我想包括我在内的每个人都曾经这样做过。不过,这很容易理解。

这是怎么回事

当您将函数作为对象的方法调用时,您将其上下文设置为对象。这意味着this该函数内部将指向您的上下文对象。

MyObject = {};
MyObject.someValue = 1;

MyObject.myMethod = function() {
    console.log(this.someValue); // This will log "1" to the console, as expected
};

现在是棘手的部分:您可以更改函数的上下文。让我们在这里添加更多代码行:

MyOtherObject = {};
MyOtherObject.someValue = 2;
MyOtherObject.myMethod = MyObject.myMethod;

当您现在调用时MyOtherObject.myMethod,您调用的函数与调用 的函数相同MyObject.myMethod,但在一种情况下this指向MyObject,在另一种情况下指向MyOtherObject

现在,当您调用 时setInterval(MyObject.myMethod, 1000),函数上下文将设置为window(从技术上讲,setInterval调用window.setInterval)并且由于window没有调用属性someValue,因此它只是未定义的。

如何修复它

要解决此问题,您可以创建另一个对 LoginScreen 对象的引用。除非您更改它,否则它将始终指向整个范围内的同一个对象。然后,您可以将其用作替代方案,this而无需担心上下文。

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对 JavaScript 中this行为的另一种解释,以及一些控制它的函数。

于 2013-10-16T09:22:02.343 回答