JavaScript中class继承必须用extends和super(),子类需显式继承单个父类并在构造函数中先调用super()再访问this;多重继承不支持,漏调或错序super()会抛ReferenceError。

JavaScript 中 class 继承必须用 extends 和 super()
ES6 的 class 语法不支持多重继承,子类必须显式继承一个父类,并在构造函数中调用 super()——否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this'。
常见错误是漏掉 super(),或在调用前访问 this(比如先写 console.log(this) 再写 super()),这都会直接抛错。
-
extends后只能跟一个构造函数或null(极少见) -
super()必须在使用this前调用,且仅限于子类构造函数内 - 若父类构造函数需要参数,
super(...args)必须传对应参数
原型链继承:手动改 Child.prototype.__proto__ 或用 Object.setPrototypeOf()
这是最底层的继承方式,绕过 class 语法,直接操作原型。适合需要动态继承、或兼容老环境(如 IE11)的场景,但易出错且可读性差。
不要直接赋值 Child.prototype = Parent.prototype——这会让子类和父类共享同一原型对象,修改子类原型会影响父类。
立即学习“Java免费学习笔记(深入)”;
- 推荐写法:
Object.setPrototypeOf(Child.prototype, Parent.prototype) - 构造函数内部仍需手动调用
Parent.call(this, ...)实现实例属性继承 - 注意:V8 引擎对
Object.setPrototypeOf()有性能警告,频繁调用会影响优化
组合继承(构造函数 + 原型链)仍是兼容性最强的通用方案
它同时解决实例属性继承(靠 Parent.call(this))和方法复用(靠原型链),没有寄生组合继承的额外函数开销,也没有 ES6 class 的语法限制。
典型结构是:子类构造函数里执行一次 Parent.call(this, ...);再用 Object.setPrototypeOf() 或 Child.prototype = Object.create(Parent.prototype) 设置原型关系。
- 避免在子类原型上直接写
constructor属性,否则会丢失原始构造器引用 - 如果用
Object.create(Parent.prototype),记得补上Child.prototype.constructor = Child - 该模式在 Node.js 早期版本、微信小程序基础库 2.0+、React Native 等环境中稳定可用
不推荐用 Object.create(null) 做继承起点
虽然 Object.create(null) 创建的对象没有 toString、hasOwnProperty 等默认方法,看起来“干净”,但它也切断了所有原型链,导致无法被 instanceof 正确识别,也无法被大多数工具(如 JSON.stringify、Lodash 的 isPlainObject)正常处理。
即使你只是想避免污染,也应优先考虑 Object.create(Parent.prototype) 或标准 class 继承。
-
obj instanceof Parent对Object.create(null)实例永远返回false -
for...in遍历时不会报错,但完全遍历不到任何继承方法 - 现代框架(如 Vue 3 的响应式系统)明确要求对象必须有原型链才能代理
class + extends;需要兼容旧环境或特殊控制时,才回到组合继承。别为了“看起来高级”而用 Object.create(null) 或反复重写 __proto__——那只会让调试变慢、协作变难。











