1.使用原型链实现继承
我们让“子类”原型对象等于“基类”的一个实例,这样“子类”原型对象就会有[[prototype]]指针指向“基类”的原型对象,这就是原型链的基本概念。
1.1实现原型链的一种基本模式:
function SuperType(){
this.property=true;
}
SuperType.prototype.getSuperValue=function(){
return this.property;
}
function SubType(){
this.subproperty=false;
}
SubType.prototype=new SuperType();
var instance=new SubType();
alert(instance.getSuperValue()); //true
SubType继承了SuperType,继承是通过创建SuperType的实例,并将该实例赋给SubType.prototype实现的,实现的本质是重写了原型对象。
1.2注意的问题
(1)给原型添加方法一定要放在替换之后,否则,重写了原型对象后,添加的方法失效。(2)不能再通过对象字面量定义“子类”SubType的方法和属性。
1.3存在的问题:
(1)原先存在于“基类”SuperType构造函数中的引用类型会变成子类SubType的原型属性。这样SubType的所有实例共享这个属性。 function SuperType(){
this.nums=[1,2,3,4,5];
}
function SubType(){
}
SubType.prototype=new SuperType();
var instance1=new SubType();
instance1.nums.push(6);
alert(instance1.nums); //1,2,3,4,5,6
var instance2=new SubType();
alert(instance2.nums); //1,2,3,4,5,6
(2) 创建子类型的时候,不能向父类型的构造函数中传递参数。
2.借用构造函数
2.1在子类型的构造函数内部调用超类型构造函数。
function SuperType(){
this.nums=[1,2,3,4,5];
}
function SubType(){
SuperType.call(this);
}
var instance1=new SubType();
instance1.push(6);
alert(instance1); //1,2,3,4,5,6
var instance2=new SubType();
alert(instance2); //1,2,3,4,5
借用构造函数的实质是在子类中用实例方法或者属性覆盖了原型中的方法或者属性。
2.2构造函数的问题
函数无法复用
3.组合继承
3.1结合原型链和构造函数,使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。
function SuperType(name){
this.name=name;
this.colors=["red"," blue","green "];
}
SuperType.prototype.sayName=function(){
return this.name;
}
function SubType(name,age){
SuperType.call(this,name); //第二次调用
this.age=age;
}
SubType.prototype=new SuperType();//第一次调用
SubType.prototype.sayAge=function(){
return this.age;
}
var instance1=new SubType("John",24);
instance1.colors.push("black");
alert(instance1.colors); //red , blue , green ,black
instance1.sayName(); // John
instance1.sayAge();//24
var instance2=new SubType("Tony",25);
alert(instance2.colors);//red ,blue , green
instance2.sayName(); // Tony
instance2.sayAge(); //27
3.2组合继承的问题
两次调用基类的构造函数。其实就是在子类构造函数里生成新的属性用了覆盖基类的属性
4.寄生组合式继承
不必为指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本。
寄生组合式继承基本模式:
function inherit(subType, superType){
var prototype=Object.create(superType.prototype);
subType.prototype=prototype;
prototype.constructor=subType;
}
function SuperType(name){
this.name=name;
this.colors=["red","blue","green"];
}
SuperType.prototype.sayName=function(){
return this.name;
}
function SubType(name,age){
SuperType.call(this,name);
this.age=age;
}
inherit(SubType , SuperType);
SubType.prototype.sayAge=function(){
return this.age;
}
var instance=new SubType("John",24);
alert(instance.sayName());