先上代码:
function SuperType(){ this.property=true; } SuperType.prototype.getSuperValue=function(){ return this.property; }; function SubType(){ this.subproperty=false; } SubType.prototype=new SuperType(); //这里继承了SuperType SubType.prototype.getSubValue=function(){ return this.subproperty; } var instance=new SubType(); alert(instance.getSuperValue()); //true
这里必须先撸一撸instance SubType SuperType之间的关系:
1.instance是SubType的实例
2.instance的原型是SuperType的实例,因为上面的代码没有使用SubType的默认原型
3.SuperType的原型对象为SuperType Prototype
4.SuperType Prototype的构造函数constructor指向SuperType的构造函数
总结起来就是:
1.instance指向SubType的原型
2.SubType的原型又指向SuperType的原型(因为构造函数肯定会有一个默认原型)
3.getSuperValue()是一个原型方法,存在于SuperType.prototype中,property是一个实例属性,位于SubType.prototype中
4.SubType的原型属性constructor属性本因指向SubType的构造函数(因为默认是这样),但却因为SubType的原型指向了另一个对象SuperType的原型(SuperType的实例的原型),而这个原型对象的constructor属性指向的是SuperType
如果没有理解,请理解后再继续....
--------------------------------------邪恶的分割线----------------------------------------
我们怎么确定原型和实例间的关系呢?
方法1:
alert(instance instanceof Object);//true 所有函数的默认原型都是Object alert(instance instanceof SuperType);//true alert(instance instanceof SubType);//true
方法2:
alert(Object.prototype.isPrototypeOf(instance));//true alert(SuperType.prototype.isPrototypeOf(instance));//true alert(SubType.prototype.isPrototypeOf(instance));//true
子类可以重写父类的方法,但是以下代码却没有重写SuperType的getSuperValue方法,并且最后一个是false,因为这种"字面量"的写法重新定义了原型,破环了继承(相当于SubTyp.prototype=new SuperType() 这句无效了):
function SuperType(){ this.property=true; } SuperType.prototype.getSuperValue=function(){ return this.property; }; function SubType(){ this.subproperty=false; } SubType.prototype=new SuperType(); //继承了SuperType SubType.prototype={ getSuperValue:function(){ return false; } }; var instance=new SubType(); alert(instance.getSuperValue()); //true alert(instance instanceof SuperType); //false
第二个注意点为:
function SuperType(){ this.friends=["gay1","gay2"]; } function SubType(){ } SubType.prototype=new SuperType(); var instance1=new SubType(); var instance1.friends.push("gay3"); alert(instance1.friends); var instance2=new SubType(); alert(instance2.friends); //gay1,gay2,gay3
看过我上一篇文章的朋友肯定还记得为什么instance2.friends包含"gay3".
使用原型链实现继承的缺点还包括:
在创建子类型的实例时,不能向父类的构造函数中传递参数,更确切的表述为:没有办法在不影响所有对象实例的情况下,给父类的构造函数传递参数.
鉴于此,一般情况下几乎没有单独使用原型链实现继承的案例.所以,我完全认同:这是一篇水文!
但希望这篇水文能有助于读者了解接下来的更实用的继承方式.待续.