浅议javascript 中继承模式 (javascript高级程序设计)
1.原型链
许多面向对象的语言都支持两种继承方式:接口继承和实现继承。
接口继承只支持方法签名(即只声明方法名称,不实现具体功能),而函数中没有签名,故在 ECMAScript中无法实现接口继承;
实现继承则继承实际的方法,在ECMAScript 中主要是依靠原型链来实现的。
原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的。这样,子类型就能够访问超类型的所有属性和方法
1 function SuperType() {
2 this.property = true;
3 }
4
5 SuperType.prototype.alertName = function() {
6 return this.property;
7 };
8
9 function SubType() {
10 this.subproperty = false;
11 }
12
13 SubType.prototype = new SuperType();
14
15 SubType.prototype.getSubproperty = function(){
16 return this.subproperty;
17 }
18 var instance = new SubType();
19
20 alert(instance.alertName());
21
22 alert(instance.getSubproperty());
3 }
4
5 SuperType.prototype.alertName = function() {
6 return this.property;
7 };
8
9 function SubType() {
10 this.subproperty = false;
11 }
12
13 SubType.prototype = new SuperType();
14
15 SubType.prototype.getSubproperty = function(){
16 return this.subproperty;
17 }
18 var instance = new SubType();
19
20 alert(instance.alertName());
21
22 alert(instance.getSubproperty());
- 原型链的缺点:
- 1.在原型对象中,如果存在引用类型值的原型属性,则被所有实例共享,那么在任何一个实例修改引用类型值,则会引起其他实例该原型属性的变化。而且在通过原型来实现继承时,原型实际上会变成另一个类型的实例,这样,原先的实例属性也就顺理成章地变成了现在的原型属性
- 2.在创建子类型的实例时,没有办法在不影响所有对象实例的情况下,向超类型的构造函数传递参数
综上两点,实践中很少会单独使用原型链。
2.借用构造函数
在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数的技术(伪造对象或经典继承)
这种技术的基本思想:在子类型构造函数的内部调用超类型构造函数.函数是在特定环境中执行代码的对象
this.colors = ["red","blue","green"];
}
function SuperType(){ function SubType(){
SuperType.call(this); //SuperType.apply(this);
}
var instance = new SubType()
}
function SuperType(){ function SubType(){
SuperType.call(this); //SuperType.apply(this);
}
var instance = new SubType()
- 借用构造函数的缺点:
- 1.代码复用性差
- 2.在超类型的原型中定义的方法,对子类型而言是不可见的
3.组合继承
- 组合继承(伪经典继承)
- 将原型链和借用构造函数的技术相结合的一种继承模式。其背后的思路是使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性的继承
4.原型式继承
道格拉斯 克罗克福介绍了一种实现继承的方法:借助原型可以基于已有对象创建新对象,无需创建自定义类型
1 function object(o){
2 function F(){}
3 F.prototype = o;
4 return new F(); 5 }
2 function F(){}
3 F.prototype = o;
4 return new F(); 5 }