2013-10-16 75 views
0

我是一名精通c#的程序員,我對HTML和Javascript有一點點經驗,但似乎無法找出對象。在JavaScript中使用'this'創建對象

我試圖創建一個循環,它只是不斷更新,直到計數器達到5,然後停止循環。但在Update方法計數器= 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(); 
+0

您是否試圖循環每一分鐘?如果是這樣,請檢查'setInterval()'參數。 – Jared

+0

我不在乎它多久循環一次,我的間隔實際上是每秒60次,但這個時候與這個問題無關 –

回答

3

的問題是你的Start()Stop()Update()功能內this的範圍。在這些函數中,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(); 

希望這是有道理的!

+1

魔獸......它確實有道理,但......魔獸......誰來設計這個。我看到我的頭會傷害嘗試在c#後學習javascript。這真的是這樣做的可接受的方式嗎? –

+1

範圍的「鬆散」是我在JavaScript中欣賞和哭泣的東西...祝你好運,並不斷學習! ;) –

+1

JavaScript是一種愛/恨的關係。你會習慣的。 :) – Jared

2

您遇到了令人畏懼的Javascript「this」問題。

試着改變你的this.Update代碼:

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

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

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

別急有more

+0

很好的答案,但克里斯擊敗你 –

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,但在一種情況下thisMyObject而在其他情況下,它指向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中beviour的另一說明中,用一些函數來控制它沿。

+0

哇...超級解釋! –