ES中只支持实现继承,且其继承是通过原型链来实现的。
基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。让一个原型对象等于另一个类型的实例。
原型链有个严重的问题,就是包含引用类型值的原型,属性会被所有实例共享。还有一个问题是无法向超类的构造函数传参。
比如:
function SuperType(){
this.colors=["blue","red"];
}
function SubType(){}
SubType.prototype=new SuperType();
var sub=new SubType();
var sub2=ew SubType();
此时sub的原型是SuperType的实例,每个subType的原型都有不同的colors数组,但是所有subType的实例都指向同一个原型,所以sub和sub1中有同一个数组。
1.为了解决上述问题,借用构造函数方法产生了
function SuperType(color){
this.colors=["blue","red"];
this.colost.push(color);
}
function SubType(){
SuperType.call(this,"black")
}
var instance=new SubType();
缺点:类似构造函数的问题,方法都在构造函数中定义无法复用
2.组合继承
将原型链和构造函数结合。使用原型链实现对源性属性和方法的继承,使用借用构造函数来实现对实例属性的继承。
function SuperType(name){
this.colors=["blue","red"];
this.name=name;
}
SuperType.somefuncion={
//
};
function SubType(name){
SuperType.call(this,name)
}
SubType.prototype=new SuperType();
SubType.constructor=SubType;
sub = new Subtype("name")
3.原型继承:在只想要一个和其他对象差不多的对象时使用可以直接用create函数,
var person={name="ha",age=10};
var anotherperson=Object.create(person)
注意这里和原型链差不多,引用类型会被所有新创建的副本共享。
其中create函数的实现是这样的:
function object(o){
function F(){};
F.prototype=o;
return new F();
}
4.寄生式继承
与原型式紧密相关,与寄生构造和函数和工厂模式类似。创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象。
function createAnother(original){
var clone=object(original);
clone.sayHi=function(){};
return clone;
}
但是同样存在不能复用的问题。
5.寄生组合式继承
组合继承有一个缺点,就是会调用两次超类的构造函数,一次是在创建子类型原型的时候,一次是在子类型构造函数的内部。
这样子类型的原型上会有多余的属性
通过这样一个函数
inherit(subtype,supertype){
var prototype=object(supertype.prototype);
prototype.constructor=subtype;
subtype.prototype=prototype;;
}
来替换subtype.prototype=new supertype();
即省略了一次调用超类构造函数的过程。
参考文献:《JS高程》