转载自:
ES3、ES5、ES6继承
两张图理解继承
Mixin继承、高阶函数、装饰器

1.对象有属性 proto, 指向该对象的构造函数的原型对象。
2.方法除了有属性 proto, 还有属性prototype,prototype指向该方法的原型对象。
(类/方法本身的 proto 指向 js 方法本身的定义,无意义)

JS 中的继承有多种实现方式,可以分成下面四类:

  • Mixin 模式,即属性混入,从一个或多个对象中复制属性到新的对象中
  • 方法借用模式,即通过 call 或 apply 实现方法的重用
  • 原型模式,使用 Object.create 方法直接以一个对象为原型创造新的对象
  • 类模式,实际上是使用构造函数或 ES6 class

前三种有一个共同点,就是没有“类”的概念,它们在适当的场景下非常有用,不过也因为没有类,缺失了很多经典面向对象继承的要素。例如父子对象之间没有严格的传承关系,即不一定是 is-a 的关系,这决定了无法将它们直接应用在面向对象分析与设计方面,可以说它们并不是真正的继承,而是介于继承和组合之间的代码复用方案。
而第四种,类式继承,无论是使用构造函数还是 ES6 加入的 class,都能表达明确的继承关系,在需要对继承重度使用的场景下,应该使用类式继承。接下来,本文讨论的都是类式继承。

有一点需要牢记:继承是一种强耦合,应该谨慎使用。

用 ES3 实现继承

实现要点:

利用 Person.call(this) 执行“方法借用”,获取 Person 的属性
利用一个空函数将 Person.prototype 加入原型链

function Person(name) {this.name = name;
}Person.prototype.printName = function() {console.log(this.name);
};function Bob() {Person.call(this, "Bob");this.hobby = "Histroy";
}function inheritProto(Parent, Child) {var Fn = function() {};Fn.prototype = Parent.prototype;Child.prototype = new Fn();Child.prototype.constructor = Child;
}inheritProto(Person, Bob);Bob.prototype.printHobby = function() {console.log(this.hobby);
};console.dir(new Bob());

用 ES5 实现继承

实现要点:

利用 Person.call(this) 执行“方法借用”,获取 Person 的属性
利用 ES5 增加的 Object.create 方法将 Person.prototype 加入原型链

function Person(name) {this.name = name;
}Person.prototype.printName = function() {console.log(this.name);
};function Bob() {Person.call(this, "Bob");this.hobby = "Histroy";
}Bob.prototype  = Object.create(Person.prototype, {constructor: {value: Bob,enumerable: false,configurable: true,writable: true}
});Bob.prototype.printHobby = function() {console.log(this.hobby);
};console.dir(new Bob());

用 ES6 实现继承

实现要点:
利用 ES6 增加的 class 和 extends 实现比以前更完善的继承

class Person {constructor(name) {this.name = name;}printName() {console.log(this.name);}
}class Bob extends Person {constructor() {super("Bob");this.hobby = "Histroy";}printHobby() {console.log(this.hobby);}
}
console.dir(new Bob());

super

使用 super 来实现更简化、更灵活的多态方法
再来看 ES6 中的 super,子类的方法想借助父类的方法完成一部分工作时,super 就可以派上用场了,这是比继承更为细粒度的代码复用,不过耦合性也也变得更强了。实际上 super 也有很多功能,既可以当作函数使用,也可以当作对象使用。

class 继承中的箭头函数

第一步,我们使用普通创建类的方式声明了一个类 A

class A {files = []startUpload = () => {...}
}

复制代码这是一个文件上传的简易类,此时我们又一个需求,就是在某种情况下需要实现在 startUpload 之前对 files 进行重新排序,为了避免强耦合,本来打算用组合或者注入高阶函数的方式实现,最后还是选择了继承。

class B extends A {sort () {...}startUpload = () => {this.sort()super.startUpload()}
}

复制代码然而问题出现了,我们使用图中的方式根本无法实现真正意义上的拓展,问题就出在了箭头函数上:

第二步分析:箭头函数是被声明在了对应的 this 上,因此在子类上二次声明 startUpload 方法是对父类 this 上属性的覆盖,而非并存。而且在语法层面上 es6 根本不允许在箭头函数上访问关键字 super。因此解决方案就是将箭头函数全部替换为对应的普通方法,将方法放到类的原型上,这样就可以实现了方法的继承,而非覆盖。

ES3、ES5、ES6继承相关推荐

  1. es5/es6 继承总结

    ES5中的继承 一 原型链继承 原型链继承的原理:直接让子类的原型对象指向父类实例,当子类实例找不到对应的属性和方法时,就会往它的原型对象,也就是父类实例上找,从而实现对父类的属性和方法的继承. // ...

  2. ES5 和ES6 继承机制

    为什么80%的码农都做不了架构师?>>>    ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this)).ES ...

  3. ES5和ES6继承的区别

    ES5的继承方法可以看这篇: https://blog.csdn.net/qq593249106/article/details/83098432 ES5与ES6的继承方法对照: ES5 functi ...

  4. ES5、ES6 继承

    es5继承类型: 原型链继承:让构造函数的原型指向父类的实例,缺点是子类没有办法构建私有属性,对一个子类实例的属性进行更改,会改变所有子类的实例 function Parent(){this.name ...

  5. ES5继承和ES6继承的区别

    ES5的继承:实质是先 创造 子类的实例对象this,然后再将父类实的方法添加到this上( Parent.apply(this) ) function Parent(name){this.name ...

  6. ES5的继承和ES6的继承

    ES5 的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this(Parent.apply(this)) ES6 的继承机制完全不同,实质上是先创建父类的实例对象this(所以必须先调用父 ...

  7. es5 vs es6 继承

    ES5 继承 借助构造函数继承(call, apply);无法继承父级原型上属性和方法 function Animal(name, txt) {console.log('构造函数:Animal', t ...

  8. es6继承 vs js原生继承(es5)

    最近在看es2015的一些语法,最实用的应该就是继承这个新特性了.比如下面的代码: 1 $(function(){ 2 class Father{ 3 constructor(name, age){ ...

  9. ES5 ES6基础知识

    ES5语法 数组方法 迭代(遍历)方法:forEach().map().filter().some().every(): array.forEach(function(currentValue, in ...

  10. ES6 继承(复习原型链继承)

    2019独角兽企业重金招聘Python工程师标准>>> 原型链继承 <script type="text/javascript">/* 原型链 继承 ...

最新文章

  1. 实时大数据开发难、运维难、应用难?来,一站解决!
  2. 【学员分享】PMcaff阿德老师精(diao)彩(bao)传道的9条干货
  3. 后台管理中心跳转问题解决
  4. object overview page打开后白屏问题分析
  5. 川大的计算机科学分数线,四川大学各排名及分数线整理_四川大学特色分享
  6. 解决数据库报唯一性约束错误的实践
  7. excel小写转大写公式_Word如何一键转PPT/Excel,来看看用对的方式操作office有多方便...
  8. Mobile端Catalog下面Category的配置步骤
  9. win10安装mysql报错——无法项识别为 cmdlet、函数、脚 本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
  10. Jupyter编程完成对手写体Mnist数据集中10个字符 (0-9)的分类识别
  11. 二硫键交联的巯基化壳聚糖水凝胶/pH、离子强度敏感性的壳聚糖水凝胶CS-GA-ASP
  12. web前端设计与开发期末作品/期末大作业【使用HTML制作汽车首页】
  13. js 实现网页内容语音朗读功能
  14. 在家里赚钱的工作,在家利用互联网赚钱,应该这样干!
  15. 启强书屋(书荒地老)
  16. bash入门脚本(未完善)
  17. 首期寄语 | 阿里游戏云马全治:伟大的改变,从“听说”开始
  18. BZOJ 1707 [Usaco2007 Nov]tanning分配防晒霜
  19. random seed什么意思
  20. 【数字电路基础】三态门

热门文章

  1. 引用 USB启动盘,将DOS工具集成到WinPE的grub - Windows
  2. 问卷调查报告html,问卷调查报告格式优秀范文
  3. 转 26款 网络会议/视频会议开源软件
  4. 人文视野中的生态学题库
  5. Oracle中TO_NUMBER()函数的用法
  6. Oracle中的数据类型---NUMBER
  7. 数电实验Verilog-数字钟
  8. 关于CSDN如何搜索用户以及关注好友
  9. 领峰:个人如何投资白银炒白银有哪些方法
  10. LDO与电压基准源的精度对比