寄生组合式继承是组合式继承和寄生式继承的结合版:
组合式继承:
JavaScript实现继承的方式主要有两种:1、通过原型链继承;2、借用构造函数;
//通过执行构造函数设置属性
function A(){
this.a = 1;
}
//通过原型设置属性
A.prototype.b = 1;
原型链继承可以实现所有属性方法的共享,但是无法做到属性方法独享。借用构造函数除了能独享属性方法外还能在子类构造函数中传递参数,但代码无法复用。正好与原型链相反,实现属性和方法的独享,无法共享。
组合式继承可以实现把共享的属性方法用原型链继承,独享的属性方法用借用构造函数实现,但实现这种形式会两次调用父类,性能上会减弱,代码如下:
function SuperType(name){
this.name = name;
this.colors =["red","blue","green"]
}
SuperType.prototype.sayName = function(){
alert(this.name);
}
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
//可共享
SubType.prototype = new SuperType();
//独享
SubType.prototype.sayAge = function(){
alert(this.age);
}
//实例
var instance1 = new SubType("Pat", 29);
instance1.colors.push("black");
aletr(instance1.colors); //red,blue,green,black
instance1.sayName; //Pat
instance1.sayAge; //29
上面代码中,两次调用了父类函数SuperType();性能上有所减弱。
寄生式继承:
与原型链继承相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。寄生式继承解决了组合式继承中两次调用父类的情况,寄生继承不用实例化父类,直接实例化一个临时副本实现相同的原型链继承,代码如下:
//寄生继承
function object(o){
function F(){};
F.prototype = o;
return new F;
}
//副本
function createAnother(original){
var clone = object(original);
clone.sayHi = function(){
alert("hi");
}
return clone;
}
//实例
var person = {
name:"Pat",
friends:["Tom", "Jack"]
}
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //hi
上述代码中创建了object()的副本createAnother(),不需要每次去调用父类。
寄生组合式继承:
集寄生式继承和组合式继承的优点与一身,实现基本类型继承的最有效方法。参考代码如下:
//寄生组合式继承
//继承原型
function extend(SubType, SuperType){
function F(){};
F.prototype = SuperType.prototype;
var prototype = new F;
prototype.constructor = SubType;
subType.prototype = prototype;
}
//超类方法
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;
}
//继承超类原型
extend(SubType, SuperType);
//子类方法
SubType.prototype.sayAge = function(){
return this.age;
}
//实例
var instance1 = new SubType("Pat");
var instance2 = new SubType("Pat", 29);
instance1.colors.push("black");
alert(instance1.colors); //red,blue,green,black
alert(instance2.colors) ; //red,blue,green
alert(instance1 instanceof SubType); //true
alert(instance2 instanceof SubType); //true
代码中只调用了一次SuperType,并且避免了SubType.prototype上面创建多余大的不必要属性,同时保持原型链不变。