主因來自於兩個:
- Internet Explore(IE)與FireFox(FF)的語法不一
- javascript並非物件導向
而第二個問題倒是比較困惱著我,好在這些問題也曾經有人遇過得以解救
主要參考的文獻都是馮旭平大大(哈~~請見諒我直呼名諱)的文章。
因為我打算用 Javascript 撰寫類別的概念,但是此語言並非Class-Based,
而是Prototype-Based,因此寫起來跟以往在寫C#與JAVA時格外不同。
當我使用 setInterval 讓圖片能夠每隔一秒顯示時卻遇到了非常大的一個問題,
問題原由請看下列程式說明:
function Timer(){
this.timer = null;
this.ini = function(){
this.timer_digit = 0;
// this.timer = setInterval(this.runTimer, 1000);
}
}
Timer.prototype.runTimer = function(){
this.timer_digit++;
alert(this.timer_digit);
}
<body onload="var b=new Timer();b.ini();">
</body>
相信大家執行這段程式碼以後會發現 alert(this.timer_digit); 會出現 NaN 而不是累加的數字,
後來我找到問題的原因即是因為 this 這個關鍵字在不同地方使用時會有不一樣的意義。
當 function 是被一個 new 出來的物件呼叫時,在呼叫時會把 this 傳給這個 function 使用,
如上例即是 this 會傳到 Timer 這個 function 內,因此這個時候使用的 this 是沒有問題的,
但是當b.ini()呼叫以後,執行到 this.timer = setInterval(this.runTimer, 1000) 之後會每隔一秒跑一次runTimer
但是當runTimer被呼叫起來的時候,已經不是由物件本身自己叫用,這個時候 this 將會變成是 Global 物件。
有興趣看 Global 物件到底是什麼可以試著把 alert 那行改為 alert(this),
最後當我把 runTimer 移到Timer 並在 Timer初始化時用一個變數記著這個new出來的物件時即可。詳情如下所示:
function Timer(){
var ref = this;
this.timer = null;
this.timer_digit = 0;
this.ini = function(){
// this.timer = setInterval(this.runTimer, 1000);
}
this.runTimer = function(){
ref.timer_digit++;
if(ref.timer_digit<5)
alert(ref.timer_digit);
}
}
實作內容請點我
沒有留言:
張貼留言