2013-02-16 55 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的原型,但是在原型链中更早。