JavaScript实现继承
什么是原型链?
ECMA-262把原型链定义为ECMAScript的主要继承方式,其基本思想就是通过原型继承多个引用类型的属性和方法。
在此之前需要掌握构造函数、原型和实例之间的关系:
每个构造函数都有一个原型对象,原型有一个属性指回这个构造函数,而实例有一个内部指针指向原型。如果这个原型是另一个原型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。
这样就在实例和原型之间形成了一个原型链。
这就是原型链的基本构想。
实现简单原型链:
下面是一个简单原型链的实现代码:
function SuperType(){
this.prototype = true
}
SuperType.prototype.getSuperValue = function(){
return this.prototype
}
function SubType(){
this.subProperty = false
}
//继承 superType
SubType.prototype = new SuperType()
SubType.prototype.getSubVaule = function(){
return this.subProperty
}
let instance = new subType()
console.log(instance.getSubVaule()) //false
console.log(instance.getSuperValue()) //true
以上代码定义了两个类型SuperType
和SubType
,这两个类型分别定义了一个属性和一个方法,然后SubType通过创建SuperType的实例并将其赋值给自己的prototype,实现了对SuperType的继承。
这个赋值重写了SubType最初的原型,将其替换成了SuperType的实例。这意味着SuperType实例可以访问的所以属性和方法也会存在于SubType的原型上。这样实现了继承之后,又给SubType的原型也就是SuperType的实例添加了一个新方法。
最后又创建了SubType的实例instance,并成功调用了它继承的getSubVaule()和getSuperValue()方法。
上面代码中实现继承的关键,是SubType没有使用默认原型,而是将其替换成了一个新的对象,这个对象就是SuperType的实例。这样,SubType的实例不仅能从SuperType的实例中继承属性和方法,而且还与SuperType的原型挂上了钩。
于是instance(通过内部的[[Prototype]])指向SubType.prototype,而SubType.prototype(作为SuperType的实例又通过内部的[[Prototype]])指向SuperType.prototype.
注意,由于SubType.prototype的constructor属性被重写为指向SuperType,所以instance.constructor也指向SuperType。
扩展补充:
原型链是原型搜索机制的扩展运用,我们都知道,在读取实例上的属性时:
- 首先会在实例上搜索这个属性
- 如果没有找到,则会继承搜索实例的原型
在通过原型链实现继承后,搜索就可以继承向上,搜索原型的原型。
对于前面的例子,instance.getSuperValue()经历了3个搜索步骤:
- instance
- SubType.prototype
- SuperType.prototype
在最后一步才找到这个方法。
对属性和方法的搜索会一直持续到原型链的顶端
参考文献
JavaScript高级程序设计—继承
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!