寄生组合式继承分析

寄生组合式继承,是集寄生式继承和组合继承的有点与一身,主要是通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function object(o){
function F(){}
F.prototype = o;
return new F();
}

function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); // create object
prototype.constructor = subType; // augment object
subType.prototype = prototype; // assign object
}

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;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function(){
alert(this.age);
};

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
instance1.sayName(); // "Nicholas";
instance1.sayAge(); // 29


var instance2 = new SubType("Greg", 27);
alert(instance2.colors); // "red,blue,green"
instance2.sayName(); // "Greg";
instance2.sayAge(); // 27

对以上代码的分析:

 

1
2
3
4
5
 function object(o){
function F(){}
F.prototype = o;
return new F();
}

 声明一个object函数,传入一个obj类型的参数,在函数的内部,声明一个函数F,F的原型指向传入的参数o,最后返回函数F

 

1
2
3
4
5
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); // create object
prototype.constructor = subType; // augment object
subType.prototype = prototype; // assign object
}

  声明函数inheritPrototype,有两个obj类型的参数,第一个是子类型的构造函数subType,第二个是超类型的构造函数superType。第一步是创建超类型原型的的一个副本prototype。第二部是为prototype副本添加constructor属性subType。(因为重写原型会失去默认的constructor属性)。第三部是将创建的prototype对象(即副本)赋值给子类型的原型。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

  声明构造函数SuperType作超类型,设置其属性及原型方法sayName;声明构造函数SubType作子类,设置其属性。子类通过构造函数继承父类的属性。  

 

1
2
3
4
5
inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function(){
alert(this.age);
};

  调用inheritPrototype函数实现了寄生组合式继承;再为SubType子类添加原型方法。

 

1
2
3
4
5
6
7
8
9
10
11
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
instance1.sayName(); // "Nicholas";
instance1.sayAge(); // 29


var instance2 = new SubType("Greg", 27);
alert(instance2.colors); // "red,blue,green"
instance2.sayName(); // "Greg";
instance2.sayAge(); // 27

  声明一个object类型的SubType的实例instance1,并传入参数,姓名会依据构造函数继承传入超类的属性中,年龄传入子类的属性中。再依据原型链继承为超类属性color添加一个参数,最后分别调用父类属性,父类方法和子类方法输出。由instance1instance2对比可以看出,两个实例属性都有属于自己的属性和方法,互不影响。


总结:
  这个例子的高效在于它只调用了一次SuperType构造函数,并且因此避免了在SubType.prototype上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能正常使用instanceof和isPototypeOf()。