js核心基础之原型对象以及原型继承(三)

来源:互联网 发布:域名需要购买解析吗 编辑:程序博客网 时间:2024/05/29 09:15

上篇原型的特点

接下来,我们来谈谈原型继承。
首先,我们来简单回顾一下构造函数、原型对象、实例三者之间的关系。
每个构造函数都有一个原型对象,原型对象中有一个指针指向构造函数,而实例中有一个内部属性指向原型对象,实际上,实例与构造函数没有直接的联系。
那么,原型链怎么实现呢?我们来看例子:

//父类function SuperType(){    this.property=true;}SuperType.prototype.getSuperValue=function(){    return this.property;}//子类function SubType(){    this.subprototype=false;}//继承SubType.prototype=new SuperType();SubType.prototype.getSubValue=function(){    return this.subprototype;}var instance=new SubType();console.log(instance.getSuperValue());//true

写到这里我们可以发现,上面定义了两个类型:SuperType和SubType,每个类型定义了一个方法和一个属性,但是,从SubType.prototype=new SuperType(); 我们可以得知,SubType的原型对象是SuperType的一个实例,也就是说SubType的原型对象指向SuperType的原型对象,而不是SubType构造函数。关系如下图:
关系图
从图中我们可以清楚地看到SubType.prototype指向了SuperType的原型对象,也就是说SubType继承了SuperType。
而instance作为SubType的一个实例,instance则指向SubType.prototype

原理:从本质上来说,是重写原型对象,通过创建SuperType的实例,再将实例赋给SubType.prototype。
一、为什么SubType的原型对象上有property、propotype等属性?
答:SuperType构造函数中定义了一个属性property,值为true,原型对象上定义了一个方法,getSuperValue()获取property属性的值,所以,SuperType的实例刚new出来的时候,本身上应该有一个property属性,值为true,而,其方法应当是原型对象上的方法。而又通常,一个实例上往往有一个内部属性[[propotype]]指向原型对象,因为SubType的原型对象是SuperType的实例,
所以,实例上该有的,SubType的原型对象它都有。
二、为什么SubType的原型对象上的constructor属性不见了?
答:刚刚我们说了,原型的继承从本质上来讲就是重写原型对象,而在重写过程中,实例化的过程是没有constructor这个属性的,我们也没有额外给它添加constructor这个属性,所以constructor也就被覆盖了。
接下来我们输出SuperType和SubType的原型对象
SuperType:

console.log(SuperType.prototype);/* getSuperValue: SuperType.prototype.getSuperValue()}* constructor:SuperType();* _proto_:Object* */

SubType:

console.log(SubType.prototype);/* property: true, * getSubValue: SubType.prototype.getSubValue() * */ 

再来看看原型链继承:

console.log(instance.getSubValue());//falseconsole.log(instance.getSuperValue());//true

实现该继承会经过三个搜索步骤:
一:搜索实例上该方法;
二:实例上搜索不到则搜索SubType原型;
三:SubType原型上搜索不到,搜索SuperType原型对象。
这样就构成了原型链。在搜索过程中,直到搜索到原型链末端才会停下来,在这里,原型链末端指的是自带的构造函数Object。

本文参考《JavaScript高级编程》

原创粉丝点击