JavaScript继承如何实现_ES6类继承怎么用【教程】

15次阅读

es6 class继承必须在子类constructor中先调super()初始化this,否则报ReferenceError;super还可调父类方法,且ES6自动维护静态和原型链继承关系。

JavaScript继承如何实现_ES6类继承怎么用【教程】

ES6 的 class 语法只是原型继承的语法糖,它本身不改变 javaScript 继承的本质——所有继承最终都落在 [[prototype]] 链上。直接用 class + extends 是最简明、最安全的写法,但必须理解 super() 的调用时机和限制。

为什么子类构造函数里必须调用 super()

在子类 constructor 中,this 在调用 super() 前是未初始化的(ReferenceError)。这是 ES6 强制的时序约束,不是可选习惯。

  • super() 必须在访问 this 之前执行,哪怕只是 console.log(this)
  • 如果子类没写 constructorjs 会自动补一个隐式构造函数并调用 super(...args)
  • 如果写了 constructor 却没调用 super(),运行时直接报错:ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
class Parent {   constructor(name) {     this.name = name;   } }  class Child extends Parent {   constructor(name, age) {     // ❌ 错误:不能在 super() 前使用 this     // console.log(this);      super(name); // ✅ 必须第一句(或至少在任何 this 访问前)      this.age = age; // ✅ 此时 this 已就绪   } }

super 不只是调构造函数,还能调父类方法

super 在方法内部指向父类的原型对象(即 Parent.prototype),可用于显式调用被重写的父方法,而不是仅限于构造函数中。

  • 在实例方法中用 super.methodName() 调用父类同名方法
  • 在静态方法中用 super.staticMethod() 调用父类静态方法
  • super 在箭头函数里不可用(因为箭头函数没有自己的 thissuper 绑定)
class Animal {   speak() {     return "Animal speaks";   }   static type() {     return "Animal";   } }  class Dog extends Animal {   speak() {     return super.speak() + " — woof!"; // ✅ 调用父类实例方法   }   static type() {     return "Dog (" + super.type() + ")"; // ✅ 调用父类静态方法   } }

ES6 继承与传统原型链继承的关键差异

ES6 class 继承强制要求子类构造函数通过 super() 初始化 this,而手写原型链(如 Child.prototype = Object.create(Parent.prototype))容易漏掉 constructor 指针修复或忘记在子构造函数里手动调 Parent.call(this, ...)

立即学习Java免费学习笔记(深入)”;

  • ES6 自动设置 Child.__proto__ === Parent(静态继承),传统方式需手动设置
  • ES6 自动保证 Child.prototype.__proto__ === Parent.prototype(原型链继承),传统方式易出错
  • ES6 子类无法用 new Parent() 替代 super();手写时若漏掉 Parent.call(this)this 就不会拥有父类实例属性
  • ES6 类内部方法默认不可枚举(Object.keys() 看不到),传统 prototype 上挂的方法默认可枚举

兼容性与真实项目中的取舍

现代浏览器node.js(≥ v6)原生支持 class/extends,Babel 编译后会降级为 function + Object.setPrototypeOf__proto__ 设置,但某些老环境(如 IE)仍需完全避免。

  • 若需支持 IE11,不能依赖 class 语法,得用 Babel + @babel/preset-env 配置目标环境
  • 注意:Babel 编译后的 super 调用会被转成 helper 函数(如 _getPrototypeOf),调试时可能变深
  • typescript 用户无需担心语法兼容性,但要注意 super() 的调用位置检查是在编译期强制的

真正容易被忽略的是:子类 constructor 中哪怕只写 return {},也必须先调 super();否则不是逻辑错误,而是语法级禁止。

text=ZqhQzanResources