1、原型链---继承通过创建父类的实例。本质上市重写原型对象
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;
}
var instance = new SubType();
alert(instance.getSubValue());
使用字面量添加的新方法,会使,继承一行的代码无效。constructor指向变了。
SubType.prototype = new SuperType();
SubType.prototype = {
getSubValue:function(){},
getName:function(){}
}
2、借用构造函数---即在子类型构造函数内部调用超类型构造函数
function SuperType(){
this.colors = ["red","blue","green"];
}
function SubType(){
//继承了SuperType
SuperType.call(this);
}
var instance = new SubType();
instance.colors.push("black");
alert(instance.colors);//"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors);//"red,blue,green"
相对于原型链的优势即可以在子类型构造函数中向超类型构造函数中传递参数call()使用
问题:方法都在构造函数中定义。
3、组合继承---原型链和构造函数技术组合到一起
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.constructor = SubType;
SubType.prototype.sayAge = function(){
return this.age;
}
var instance1 = new SubType("Nicholas",20);
instance1.colors.push("black");
alert(instance1.colors);//"red,blue,green,black"
instance1.sayName();//"Nicholas"
instance1.sayAge();//20
var instance2 = new SubType("Jemmy",30);
alert(instance2.colors);//"red,blue,green"
instance2.sayName();//"Jemmy"
instance2.sayAge();//30
//避免了原型链和构造函数的缺点。
4、原型式继承--借助原型可以基于已有的对象创建新对象
function object(o){
function F(){}
F.prototype = o;
return new F();
}
在object函数内部先创建一个临时的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。
从本质上讲,object()对其传入其中的对象执行了一次浅复制
var person = {
name:"Nicholas",
fridens:["Shelby","Court","Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.fridens.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.fridens.push("Barbie");
alert(person.fridens);//""Shelby,Court,Van,Rob,Barbie"
ECMAScript5通过熙增Object.create()方法规范了原型式继承与上面的object()行为相同。
var person = {
name:"Nicholas",
fridens:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.fridens.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.fridens.push("Barbie");
alert(person.fridens);//""Shelby,Court,Van,Rob,Barbie"
5、寄生式继承--创建一个仅用于封装继承过程的函数。该函数内部以某种方式来增强对象,最后再像真地是它做了所有工作一样返回对象。
function createAnother(original){
var clone = create(original);
clone.sayHi = function(){
alert("HI");
};
return clone;
}
var person = {
name:"Nicholas",
fridens:["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();//"HI"
//create()不是必须的,只要能够返回新对象的函数都适用于此模式。
6、寄生组合式继承--组合式继承问题就是无论在什么情况下,都会调用两次超类型构造函数。一次是在创建子类型原型的时候。另一次在子类型内部
寄生组合式继承即通过借用构造函数来继承属性,通过原型链混成形式来继承方法,本质:不必为了指定子类型的原型而调用超类型的构造函数
function inheritProrotype(SubType,SuperType){
var prototype = create(SuperType.prototype);
prototype.constructor = SubType;
SubType.prototype = prototype;
}