谨慎地定义方法
子类型有时候需要覆盖超类型中的某个方法,或者需要添加超类型中不存在的某个方法。但不管怎样,给原型添加方法的代码一定要放在替换原型的语句之后。来看以下的例子:
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}
function SubType() {
this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();
//添加新方法
SubType.prototype.getSubValue = function() {
return this.subproperty;
}
SubType.prototype.getSuperValue = function() {
return false;
}
var instance = new SubType();
alert(instance.getSuperValue()); //false
在以上代码中,加粗的部分是两个方法的定义。第一个方法getSubValue()被添加到了Subtype中。第二个方法getSuperValue()是原型链中已经存在的一个方法,但重写这个方法将会屏蔽原来的那个方法。换句话说,当通过SubType的实例调用getSuperValue()时,调用的就是这个重新定义的方法;但通过SuperType的实例调用getSuperValue()时,还会继续调用原来的那个方法。这里要给外注意的是,必须在用SuperType的实例替换原型之后,再定义这两个方法。
如果反过来:
SubType.prototype.getSubValue=function(){};
//现在SubType上有了getSubValue方法
SubType.prototype=new SuperType();
//现在prototype被覆盖了,之前定义的getSubValue等方法都没了
所以,自定义的扩展要在继承父类之后进行!
还有就是,在通过原型链实现继承时,不能使用对象字面量创建原型方法。因为这样做就会重写原型链,如下面的例子所示:
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}
function SubType() {
this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();
//使用对象字面量添加新方法,会导致上一行代码无效
SubType.prototype = {
getSubValue: function() {
return this.subproperty;
},
someOtherMethod: function() {
return false;
}
};
var instance = new SubType();
alert(instance.getSubValue()); //error!
以上代码展示了刚刚把SuperType的实例赋值给原型,紧接着又将原型替换成一个对象字面量而导致的问题。由于现在的原型是一个Object实例,而非SuperType的实例,因此我们设想中的原型链已经被切断——SubType和SuperType之间已经没有关系了。