一、原型链
基本思想:让一个引用类型继承另一个引用类型的属性和方法。
构造函数、原型、实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针。
原型链继承实例:
function SuperType(){
this.property=true;
};
SuperType.prototype.getSuperValue=function(){
return this.property;
};
function subType(){
this.subProperty=false
};
subType.prototype=new SuperType();
subType.prototype.getSubValue=function(){
return this.subProperty;
};
var instance=new subType();
alert(instance.getSuperValue());//True
实例中定义了两个类型:SuperType和subType,两者分别定义了一个属性和一个方法。主要过程为:subType的实例中包含一个指针指向subType的原型,而subType的原型经由SuperType的实例指向SuperType的原型。总而言之继承的本质是重写原型对象,代之以新类型的实例。
注意:1、给原型添加方法的代码一定要放在替换原型的语句之后。
2、不能使用对象字面量创建原型方法。
3、由于引用类型值的原型属性会被所有实例共享,在通过原型实现继承的时候,原型实际上会变成另外一个类型的实例,于是原先的实例就顺理成章地变成了现在的原型属性。
4、创建子类型的实例时,不能向超类型的构造函数中传递参数。
二、借用构造函数
基本思想:在子类型构造函数的内部调用超类型构造函数(借用apply、call)
构造函数继承实例:
function SuperType(){
this.name=name;
}
function SubType(){
//继承SuperTye,同时传递参数
SuperType.call(this,"zjj");
//实例属性
this.age=29;
}
var instance=new SubType();
alert(instance.name);
alert(instance.age);
注意:如果仅仅借用构造函数,方法都在构造函数中定义,无法实现函数复用。
三、组合继承
基本思想:使用原型链实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承。
组合继承实例:
function SuperType(){
this.name=name;
this.color=["red","blue","green"];
}
SuperType.prototype.sayName=function(){
alert(this.name);
}
function SubType(name,age){
//继承SuperTye,同时传递参数
SuperType.call(this,name);
//实例属性
this.age=age;
}
SubType.prototyepe=new SuperType();
SubType.prototype.sayAge=function(){
alert(this.age);
}
var instance1=new SubType("zjj",25);
instance1.push("black");
alert(instance1.color);//"red","blue","green","black"
alert(instance1.sayName);//zjj
alert(instance1.sayAge);//25
var instance2=new SuperType("zj",22);
alert(instance2.color);//"red","blue","green"
alert(instance2.sayName);//zj
alert(instance2.sayAge);//22