JS中由于没有签名,其面向对象中,只有实现继承,没有接口继承。实现继承是通过原型链来实现的。
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.getSuperValue()); //true
上面的实例中的实例、原型和构造函数之间的关系如图所示:
由于 SubType 的原型指向了另一个对象——SuperType 的原型,而这个原型对象的 constructor 属性指向的是 SuperType。所以instance的构造函数现在指向的是SuperType。
所有函数的默认原型都是Object的实例,所以上面的原型链中实际上还有一个Object层,如下所示:
SubType 继承了 SuperType,而 SuperType 继承了 Object。当调用 instance.toString()时,实际上调用的是保存在 Object.prototype 中的那个方法。
确定原型和实例之间的关系
instanceof 操作符,只要用这个操作符来测试实例与原型链中出现过的构造函数,结果就会返回 true。
alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true
isPrototypeOf()方法,只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型,因此 isPrototypeOf()方法也会返回 true。
alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true
注意
- 子类如果需要对父类的属性、方法进行覆盖或添加新的方法,要在使用父类的实例替换原型后再进行。
- 通过原型链实现继承时,不能使用对象字面量创建原型方法,因为这样做就会重写原型链