深入解析:ES5 与 ES6 继承机制的本质区别

作者:小括号

时间:2026-10-24

浏览:151

本文深入对比 ES5 与 ES6 的继承实现。ES5 通过原型链和 apply 先创建子类实例再绑定父类方法;ES6 则先创建父类实例再修改子类指针。重点解析 super 关键字的双重用法及静态方法特性,并说明 ES6 能继承原生构造函数而 ES5 不能的原因。

文章目录

继承方式

ES5 prototype 继承

ES5 的继承依赖于原型链机制,即通过构造函数与 [[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 继承

ES6 通过 class 关键字结合 extends 和 super 来实现继承。子类自身没有自己的 this 对象,因此必须在 constructor 构造函数中通过调用 super 来继承父类的 this 对象,之后才能对该 this 对象添加子类特有的方法和属性。super 关键字在构造函数中代表父类的构造函数,用于新建父类的 this 对象。在内部实现机制上,ES6 的继承方式与 ES5 截然不同:它实质上是先创建父类的实例对象 this(这需要提前调用 super 方法),然后再使用子类的构造函数来修改 this 指针。

super 用法

super 关键字既可以作为函数使用,也可以作为对象使用。当作为函数使用时,它只能在子类的构造函数中调用,表示父类的构造函数。值得注意的是,此时 super 内部的 this 指向的是子类的实例,因此在子类中调用 super() 等价于 Father.prototype.constructor.call(this)。当作为对象使用时,super 表示父类的原型对象,即等同于 Father.prototype。

二者区别

ES5 与 ES6 的继承并非完全相同,主要存在以下几个差异点:

  1. 语法写法不同。ES6 的继承通过 extends 关键字以及 super 函数和方法来实现(关于 super 实现继承的具体使用方式,此处不再展开)。
  2. 定义在类内部的方法均为不可枚举属性,这与 ES5 的行为不同。
  3. 类定义不存在变量提升现象,这一点与 ES5 完全不同。
  4. 类相当于其实例的原型,因此在类中定义的所有方法都会被实例继承。如果在方法前加上 static 关键字,则表示该方法不会被实例继承,而是直接通过类名调用,这被称为静态方法。
  5. 内部实现机制存在显著差异。

ES5 prototype 继承内部实现方式

ES5 的继承机制实质上是先创建子类的实例对象 this,然后再将父类的方法添加到子类(this)上,其操作类似于 Father.apply(this)。

继承方式

ES6 class 继承内部实现方式

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

继承方式

由于实现机制的不同,这两种继承方式在继承原生构造函数时表现出显著差异:

ES5 的写法无法继承原生构造函数(例如 Array、Number 等)。这是因为 ES5 的继承是先创建子类的实例对象 this,再将父类原型的属性和方法重写到子类上。由于无法访问父类的内部属性,导致 ES5 的继承方式无法继承原生构造函数。相比之下,ES6 允许继承构造函数并生成子类。因为 ES6 是先创建父类的实例对象 this,然后再用子类的构造函数进行修饰,所以子类可以继承父类的所有属性和方法。因此,class 可以继承并自定义原生构造函数的子类。extends 不仅可用于继承类,还能用于继承原生构造函数,从而在原生数据结构的基础上构造自定义的数据结构。

扩展

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

到此这篇关于 JS 中 ES6 继承和 ES5 继承之间的差别的文章就介绍到这了,更多相关 ES6 继承和 ES5 继承的差别内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章