
JS中的三种继承模式(原型链继承、借用构造函数继承、组合继承及ES6中class的实现原理)
②其输出结果为:Supper()
③为了寻找这个问题的原因,我们直接打印输出sub对象。
④输出结果如下:
我们发现果然是通过Suppuer的原型对象的constructor才找到的Supper,这显然是错误的。
解决方法:重新定向Sub.prototype.constructor = Sub;(代码的38句)
如此即可将这个bug消除。
接下来我们通过实例来进行演示。
(注:此方法实质上是一种假继承,强行调用父类的构造函数,从而为子类添加属性,这里面其实没有继承,只是简化代码罢了。)
这种方法的好处: ①对于属性:继承于父类的属性,单独存储在子类型实例对象中,因此每个实例对象的属性互不影响。 ②对于方法:方法则是通过原型链进行查找调用,在执行过程中通过this进行属性的动态绑定,因此不会在堆内存中占用多余的空间。
因此更规范的方法是用
发布日期:2021-05-12 21:17:51
浏览次数:25
分类:精选文章
本文共 1814 字,大约阅读时间需要 6 分钟。
JS中的三种继承模式
写在前面:如果此篇博客中有任何错误的地方,欢迎大家的指正!让我们共同进步! 如果觉得这篇博客有用就点赞+收藏+关注三连吧!
JS中的继承模式大体分为三种: ①原型链继承 ②借用构造函数继承 ③组合继承
接下来让我们逐个的对其进行剖析。

方式一、继承模式-原型链继承
为了更好的理解为什么要这样做,我们来看一看这样做的图示:
代码核心思路: 通过将子类型的原型赋为父类型的一个实例对象,使得在创建子类的实例对象的时候可以逐步通过__proto__属性(隐式原型链)查找到父类的方法。
注意: 由于把子类型的prototype指向了另外一个对象,因此要注意子类型的方法要在继承后在写入,防止添加到普通的空Object实例对象后,由于指向重置,使其变为垃圾对象,从而丢失子类型自己的方法。
弊端思考:
这样就使得子类的实例也可以调用父类的方法啦! 但是仔细观察一下这个图示,相信悉心的同学已经发现了一个Bug。①如果我们这样输出:




图示理解如下:我们通过sub调用constructor,实际是从原型链依次查找,最终只在Supper的Prototype中查找到的constructor,因此指向的是Supper()。


方法二、继承模式-借用构造函数继承


执行结果如下:

通过整合第一种方法和第二种方法的思路,进而有了第三个方法——组合继承。
方式三、继承模式-组合继承
组合的方法分为两步
①利用原型链实现对父类型对象的方法继承 ②利用call()借用父类的构造函数初始化相同的属性接下来让我们看一个实例。

但是在实际代码书写时,这样constructor也会被for…in遍历到,

defineProperty
方法来修复constructor
的指向,并控制访问权限。 function Dog() { this.name = 'puppy'}Dog.prototype.bark = () => { console.log('woof!woof!')}function BigDog() { }BigDog.prototype = new Dog()// 修复constructor的指向Object.defineProperty(BigDog.prototype, "constructor", { value: BigDog, enumerable: false, })const bigDog = new BigDog()console.log(bigDog.constructor === BigDog)
如果用上面两个问题去测试,会发现ES6中的class实际是上面这种写法的语法糖实现。
class Cat { constructor(props) { this.name = 'puppy' } }class BigCat extends Cat { constructor(props) { super(props) }}const bigCat = new BigCat()console.log(bigCat.constructor === BigCat) //truefor(let i in bigCat){ console.log(i)} // 不会出现constructor属性
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2025年04月21日 03时07分38秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
js编写动态时钟
2021-05-09
JavaSE总结
2021-05-09
手动造轮子——基于.NetCore的RPC框架DotNetCoreRpc
2021-05-09
Python IO编程
2021-05-09
CSS入门总结
2021-05-09
使用 TortoiseGit 时,报 Access denied 错误
2021-05-09
基于 HTML5 WebGL 的污水处理厂泵站自控系统
2021-05-09
[系列] Go gRPC 调试工具
2021-05-09
django-表单之模型表单渲染(六)
2021-05-09
c++之程序流程控制
2021-05-09
一位年轻而优秀的.NET开发者的成长点滴
2021-05-09
如何使用ABP进行软件开发(1) 基础概览
2021-05-09
AlwaysOn配置时在连接步骤时报错(35250)
2021-05-09
排序算法之总结
2021-05-09
微软云Linux服务器 Mysql、tomcat远程连接错误解决办法
2021-05-09
Python数据分析(二): Numpy技巧 (2/4)
2021-05-09
09 . Python3之常用模块
2021-05-09
Python学习笔记-StatsModels 统计回归(3)模型数据的准备
2021-05-09
Velocity.js初步
2021-05-09