ECMAScript 中描述了原型链的概念,并将原型链作为实现集成的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
构造函数、原型和实例的关系:
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
那么,假如我们让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型(原型2)的指针,显然原型2中也包含一个指向构造函数2的指针,同样的,原型2又是原型3的实例,层层递进,就构成了实例与原型链的链条。即原型链。
代码演示如下:
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
以上代码定义了SuperType和SubType这两个类型,其分别有一个属性和方法。通过创建SuperType的实例,并将该实例赋给SubType.prototype,实现了Subtype对SuperType的继承。因此,SuperType的所有属性和方法,现在也存在于SubType.prototype中。之后,我们又给SubType.prototype添加了方法getSubValue,这样就在继承了SuperType的属性和方法的基础上又添加了一个新方法。
关系图结合上边的例子,根据原型搜索机制,调用instance.getSuperValue()会经历sanger搜索步骤:搜索实例→搜索SubType.prototype→搜索SuperType.prototype,最后找到该方法。
所有函数的默认原型都是object的实例,因此默认原型都会包含一个指向object.prototype的内部指针。因此,所有自定义类型才会继承toString()、valueOf()等默认方法。
确定原型和实例的关系:
- instanceof 操作符:
alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true
- isPrototypeOf()方法
alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true
注意
- 给原型添加方法的代码一定要放在替换原型的语句之后
- 不能使用对象字面量创建原型方法
- 包含引用类型值的原型属性会被所有实例共享
网友评论