2013-02-16 29 views
2

我想要做的是讓子對象爲基礎對象中定義的函數提供自己的實現。據我瞭解,到目前爲止,原型是最好的(唯一的)方式去做這件事。如何從基礎對象繼承函數並在javascript中覆蓋它

請注意,我目前正在開發使用遊戲引擎:Turbulenz,因此我正在儘可能密切關注/堅持自己的風格。在引擎「類」 /對象定義和創建以下列方式

function baseObject() { } 
baseObject.prototype = 
{ 
    myMember1: 1, 
    myMember2: 2, 

    myMethod: function myMethodFn() { 
     return this.myMember1 + this.myMember2; 
    } 
} 

baseObject.Create = function baseObjectCreateFn 
{ 
    var o = new baseObject(); 
    return o; 
} 

這將允許我做以下

var anObject = baseObject.Create(); 
var someValue = anObject.myMethod(); // should return 3 

我想做些什麼能現在是做創建一個新的對象,繼承baseObject的所有屬性,同時允許我覆蓋其myMethod函數,例如減去兩個成員值而不是添加。

我說我必須創建另一個對象,然後改變它的原型嗎?最讓我注意的部分是baseObject原型的定義被定義爲對象字面量,所以我不確定覆蓋其中一個成員的語法,也就是說以下內容是否有效? :

function childObject() {} 

childObject.prototype = baseObject.Create() // would this inherit from baseObject? 
// or should it be: childObject.prototype = new baseObject(); 

// this is the part thats confusing me as the syntax 
// doesn't quite match the original base objects prototype 
// syntax and I'm unsure if that will matter 
childObject.prototype.myMethod = function myMethodFn() { 
    return this.myMember1 - this.myMember2; 
} 

childObject.Create = function childObjectCreateFn 
{ 
    var o = new childObject(); 
    return o; 
} 

var aChildObject = childObject.Create() 
var anotherValue = aChildObject.myMethod() // would this return -1 as expected? 

總結我試圖創建一個對象,將覆蓋從基礎對象繼承的功能,改變它的基本對象存在的功能,我該怎麼辦呢?謝謝你的時間。

回答

1

你說得對。

至於語法混亂,存在的是,在第二個要一次設置原型所有

thing.prototype.myMethod = function() { ... } 

thing.prototype = { myMethod: function() { ... } }; 

除了事實之間沒有真正的區別(至object literal),如果再次執行該操作,則會用新的對象字面值立即覆蓋的原型。但是因爲它是一個對象字面,所以你不能這樣做繼承(用裸括號{ ... }聲明的所有東西只是Object沒有特殊類型的一個實例)。如果你堅持使用第一種語法,你將永遠沒問題。

注意,當你把:

childObject.prototype.myMethod = function myMethodFn() { ... } 

,你把myMethodFn的部分實際上被忽略。該功能被命名爲myMethod,因爲這是您分配的位置。

同樣,在這裏你有

childObject.Create = function childObjectCreateFn 

你不需要childObjectCreateFn(它忽略),你需要function後把括號()地方,或者它是一個語法錯誤。

繼續討論這個原因,Javascript中的每個創建的對象都有一個原型。當您在該對象上調用某個方法時,它首先在對象本身內部查找以查看與方法名稱相對應的鍵是否存在。如果沒有,它會在原型對象中查找同樣的東西,如果它不在那裏,則會轉到該對象的原型,等等,直到到達根目錄Object,該根目錄沒有原型。

通過這種方式,您可以僅通過將實現命名爲同一事物來重寫某個實現,但讓它早於原型鏈中出現。這正是你在childObject上所做的。它保留baseObject的功能,因爲您創建了一個baseObject實例來充當childObject的原型。然後你用一個同名的新方法增加了childObject的原型,但是在原型鏈中更早。