继承方式

ES5 prototype 继承

通过原型链(构造函数 + [[prototype]])指向实现继承。 (备注:后续__proto__我都会写成[[prototype]]这种形式)

子类的 prototype 为父类对象的一个实例。因此子类的原型对象包含指向父类的原型对象的指针,父类的实例属性为子类原型的属性。

// 父类:function SuperType;子类:function SubType;
SubType.prototype = new SuperType(); // SubType 继承 SuperType

// 根据上一节原型链讲到的知识点:实例化对象的__proto__等于构造函数的prototype
SubType.prototype.__proto__ === SuperType.prototype // true

上边的继承关系如下图:

内部实现机制上,ES5 的继承,实质是先创造子类的实例对象this上,然后再将父类的方法添加到这个this上。类似使用:Father.apply(this)

ES6 class 继承

通过class的extends + super实现继承。

子类没有自己的this对象,因此必须在 constructor 中通过 super 继承父类的 this 对象,而后对此this对象进行添加方法和属性。

super关键字在构造函数中表示父类的构造函数,用来新建父类的 this 对象。

内部实现机制上,ES6 的继承机制完全不同,实质是先创造父类的实例对象this---需要提前调用super方法,然后再用子类的构造函数修改this指针。

super用法

super 可以作为函数和对象使用的。

当作为函数使用的时候,只能在子类的构造函数中使用----表示父类的构造函数,但是 super 中的 this 指向的是子类的实例,因此在子类中super()表示的是 Father.prototype.constructor.call(this)。

当作为对象使用的时候,super表示父类的原型对象,即表示 Father.prototype

二者区别

答:不是完全一样的,主要有以下几个差异点

  1. 写法不一样。class的继承通过extends关键字和super函数、super方法继承。(关于super实现继承的使用方式,具体我就不展开了)
  2. 类内部定义的方法都是不可枚举的,这个 ES5 不一样
  3. 类不存在变量提升,这一点与 ES5 完全不同
  4. 类相当于实例的原型,所有在类中定义的方法都会被实例继承。如果在一个方法前,加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就成为静态方法
  5. 内部实现机制不一样。

ES5 prototype 继承 内部实现方式

ES5的继承,实质上是先创造子类的实例对象this,然后再将父类的方法添加到子类(this)上面---Father.apply(this)。

ES6 class 继承 内部实现方式

ES6的继承机制完全不同,实质上是先创造父类的实例对象this,并将父类的属性和方法放到this上(前提是通过super函数调用),然后再用子类的构造函数修改this。

因为实现机制不同,导致这两种继承在继承原生构造函数时有些差异:

es5的写法不能继承原生构造函数(比如Array、Number等)

因为es5的继承是先创造子类的实例对象this,再将父类原型的属性和方法重写到子类上,因为没法访问父类的内部属性,导致es5的继承方式无法继原生的构造函数

es6允许继承构造函数生成子类。因为es6是先创建父类的实例对象this,然后再用子类的构造函数修饰,所以子类就可以继承父类的所有属性和方法。因此class可以继承并自定义原生构造函数的子类。extends不仅可以用来继承类,还能用来继承原生构造函数,因此也就可以在原生数据结构的基础上,构造自定义的数据结构。

扩展

关于内部实现机制的说明,可以参考《阮一峰的es6文档-class的继承》相关部分

文中有不妥之处欢迎留言讨论,更多【每日一题】尽在公众号 【前端印记】

ES6继承和ES5继承是完全一样的么?的更多相关文章

  1. es5继承和es6类和继承

    es6新增关键字class,代表类,其实相当于代替了es5的构造函数 通过构造函数可以创建一个对象实例,那么通过class也可以创建一个对象实列 /* es5 创建一个person 构造函数 */ f ...

  2. ES6中的类继承和ES5中的继承模式详解

    1.ES5中的继承模式 我们先看ES5中的继承. 既然要实现继承,首先我们得要有一个父类. Animal.prototype.eat = function(food) { console.log(th ...

  3. js重新讲解继承,es5的一些继承,es6继承的改变 ----------由浅入深

    es5 利用原型公有私有继承 function Parent(name) { this.name = name } Parent.prototype.home = '北京'; function Chi ...

  4. 【ES6】更易于继承的类语法

    和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态.派生.抽象.迭代.单例等,而且根据 ES6 的新特性衍生出很多有趣的用法. 一.类的基本定义 ...

  5. 通过原型继承理解ES6 extends 如何实现继承

    前言 第一次接触到 ES6 中的 class 和 extends 时,就听人说这两个关键字不过是语法糖而已.它们的本质还是 ES3 的构造函数,原型链那些东西,没有什么新鲜的,只要理解了原型链等这些概 ...

  6. ES6中的CLASS继承

    ES6中的CLASS继承:https://www.jianshu.com/p/3d3d52b47762 es6 javascript的Class 类的继承:https://blog.csdn.net/ ...

  7. ES6中class的继承

    extends 子类的继承 super(); 调用父类的构造方法,只能在子类中执行 继承可以让子类获得父类的方法 属性,可以扩充 增加新的方法 属性等 父类(基类)--被继承的类 子类--继承后的类 ...

  8. ES5继承

    原型继承 <script type="text/javascript"> function Father(){}//构造函数 //原型属性 Father.prototy ...

  9. ES6 Class vs ES5 constructor function All In One

    ES6 Class vs ES5 constructor function All In One ES6 类 vs ES5 构造函数 https://developer.mozilla.org/en- ...

随机推荐

  1. RabbitMQ重试机制

    消费端在处理消息过程中可能会报错,此时该如何重新处理消息呢?解决方案有以下两种. 在redis或者数据库中记录重试次数,达到最大重试次数以后消息进入死信队列或者其他队列,再单独针对这些消息进行处理: ...

  2. 欧拉函数&筛法 模板

    https://blog.csdn.net/Lytning/article/details/24432651    记牢通式 =x((p1-1)/p1) * ((p2-1)/p2)....((pn-1 ...

  3. 保存TextBox中的文字为Path功能

    保存TextBox中的文字为Path功能 今天再设计一个我自己程序的Icon时使用了Path+textbox做了图形,我不想导出为PNG,因为颜色比较单一,我又想通过代码控制颜色,所以我想完整的保存为 ...

  4. WPF教程九:理解WPF中的对象资源

    在WPF中,所有继承自FrameworkElement的元素都包含一个Resources属性,这个属性就是我们这篇要讲的资源. 这一篇讲解的资源是不是上一篇的程序集资源(那个是在编译过程中打包到程序集 ...

  5. 从源码角度谈谈MySQL "Too many open files"错误的根本原因

    "Too many open files"是一个比较常见的错误,不仅仅是在 MySQL 中.只要是在 Linux 中启动的进程,都有可能遇到这个错误. 究其原因,是进程打开的文件描 ...

  6. 安卓源码默认开启USB调试

    找到\frameworks\base\services\usb\java\com\android\server\usb\UsbDeviceManager.java下的 Settings.Global. ...

  7. Java集合中的可变参数

    可变参数: 1.在JDK1.5之后,如果我们定义一个方法需要接收多个参数,并且多个参数类型一致,我们可以对其简化成如下格式: 修饰符 返回值类型 方法名(参数类型... 形参名){} 其实这个书写完全 ...

  8. python -- 程序的结构语句

    一.顺序结构 顺序结构是python脚本程序中基础的结构,它是按照程序语句出现的先后顺序进行依次执行 二.选择结构 选择结构是通过判断某些特定的条件是否满足来决定程序语句的执行顺序 常见的有单分支选择 ...

  9. 9Java基础总结

    1.psvm定义的意义 public:保证了方法的访问权限 static:保证在类未被实例化的时候就能调用(加载的时机) void:不需要返回值 main:约定俗成的名字 String[] args: ...

  10. Linux虚拟机扩展磁盘

    Linux虚拟机扩展磁盘 1.虚拟机关机,Vmware中扩展磁盘 2.虚拟机开机,查看磁盘大小 [root@hadoop6 ~]# df -h 文件系统 容量 已用 可用 已用% 挂载点 devtmp ...