@H_404_0@Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承。
@H_404_0@原型链是JavaScript中继承的主要方法。
@H_404_0@原型链的基本思想是:利用原型让一个引用类型继承另一个引用类型的属性和方法。
@H_404_0@构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。 @H_404_0@如果让原型对象等于另一个对象的实例,这样原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。 @H_404_0@实现原型链的基本模式:
默认的原型
@H_404_0@所有引用类型都默认继承了Object,而这个继承也是通过原型链实现的。所有函数的默认原型都是Object的实例。因此默认原型都会包含一个内部指针,指向Object.prototype。这就是为什么自定义类型都会继承toString()、valueOf()等方法的原因。 @H_404_0@完整的原型链: @H_404_0@在上面的继承体系中,SubType继承了SuperType,SuperType继承了Object。当调用了instance.toString()时,实际调用的是保存在Object.prototype中的那个方法。 @H_404_0@确定实例和原型的关系
@H_404_0@可以通过两种方式来确定原型和实例之间的关系: @H_404_0@使用instanceof操作符
使用isPrototypeOf()方法
谨慎定义方法
@H_404_0@给原型添加方法的代码一定要放在替换原型的语句之后。添加方法
SubType.prototype.getSubValue = function () {
return this.subproperty;
};
// 覆盖超类中的方法
SubType.prototype.getSuperValue = function () {
return false;
};
var instance = new SubType();
alert(instance.getSuperValue()); // false
@H_404_0@上面的例子必须注意的是,在用SuperType的实例替换原型之后,再定义那两个方法。
@H_404_0@另外,在通过原型链实现继承时,不能使用该对象字面量创建原型方法。因为这样做会重写原型链:
添加新方法,导致上一行代码无效
SubType.prototype = {
getSubValue :function() {
return this.subproperty;
},someOtherMethod: function () {
return false;
}
};
var instance = new SubType();
alert(instance.getSuperValue()); // error
@H_404_0@上例将SuperType的实例赋值给原型,紧接着又将原型替换成一个对象字面量而导致的问题。现在的原型包含一个Object的实例,而非SuperType的实例,SubType和SuperType之间已经没有关系了。
@H_404_0@