2011-03-17 82 views
10

我剛開始在javascript中使用oop,我遇到了一些問題,試圖從另一種方法中訪問一個方法。JavaScript對象,自引用問題

這裏是我的代碼:

var Game = { 
initialize: function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 

     this.update(); 
    } 
}, 

update: function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
}, 

draw: function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 

    setTimeout(this.update, 10); 
}, 

clear: function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
} 

}

但在調用Game.update()給出的是牽引方法沒有定義的錯誤。 我找不到一個真正的解決方案。 最終我發現這個How to call a method inside a javascript object 其中的答案似乎是,我需要安全這個參考文獻,如: var _this = this; 但我無法得到那個在文字符號的工作,所以我改變了代碼,對象構造函數(我猜這就是它的調用方式)並添加了變量。

我再改

this.draw(); 

_this.draw(); 

和它的工作。

雖然

this.clear(); 

和this.update()仍然是相同的,他們似乎從來沒有放棄在首位的錯誤。

任何人都可以解釋爲什麼這是?也許可以指點我一個更好的解決方案? 在此先感謝。

更新

下面是它應該是什麼:

var Game = function() { 
var _this = this; 

this.initialize = function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 

     this.update(); 
    } 
} 

this.update = function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
} 

this.draw = function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 


    setTimeout(function() { _this.update(); }, 10); 
} 

this.clear = function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
} 

}

+0

你能展示完整的代碼嗎? – 2011-03-17 13:30:13

+3

+1,真是太棒了,併發布您的更新。這篇文章最後闡述了備用命名空間方法的不同之處。你今天讓我成爲了一個更好的編碼器。 :) – Evildonald 2012-11-16 06:26:01

回答

14

當你這樣做:

setTimeout(this.update, 10); 

正確的引用傳遞到你的「更新」功能的系統,但是當瀏覽器實際上是調用該功能後,它不知道什麼this應該是。你可以做的,而不是爲以下:

var me = this; 
setTimeout(function() { me.update(); }, 10); 

這將確保在「更新」之稱,它將被this正確設置爲您的對象的引用調用。

與其他一些語言不同,函數最初定義爲對象的屬性並不會將函數內在地綁定到該對象。以同樣的方式,如果你有一個對象與propertly這是一個簡單的數字:

maxLength: 25, 

好值「25」不會有什麼特別做的對象;這只是一個價值。在JavaScript中,函數也是值。因此,程序員有責任確保this將被設置爲適當的東西,無論何時以某種「特殊」方式調用函數。

+0

嘿,謝謝你的驅動器downvote,朋友! – Pointy 2011-03-17 13:37:19

+0

恩,對不起。我無法回想你投票。它一定是錯誤的點擊。 – RoToRa 2011-03-18 13:45:30

+0

它可能不是你,@RoToRa - 它可能仍然是一個謎:-) – Pointy 2011-03-18 13:48:38

0

您的問題是,你使用對象文本,而不是一個實例化對象

嘗試做用這種方式代替:

var Game = function() { 
    this.initialize = function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 
     this.update(); 
    } 
    }; 
    this.update = function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
    }; 

    this.draw = function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 

    setTimeout(this.update, 10); 
    }; 

    this.clear = function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
    }; 
} 

現在用途:

var myGame = new Game(); 
+0

只是我認爲的問題的一部分... – Pointy 2011-03-17 13:31:23

+2

'this'的一個非常好的參考:http://bonsaiden.github.com/JavaScript-Garden/#function.this – adrian 2011-03-17 13:33:03

+1

@Pointy:true,setTimeout是肯定會失敗,但似乎你是覆蓋:) – 2011-03-17 13:36:46