javascript中如何实现继承机制【教程】

8次阅读

es6 class继承需用extends且子类构造函数必须先调用super(),否则报错;super()须在this前且仅一次;未定义constructor时自动补全;静态方法和getter/setter可继承但this不自动绑定;本质是设置prototype.__proto__和__proto__两层链接。

javascript中如何实现继承机制【教程】

javaScript 中 class 继承的写法和限制

ES6 的 class 语法只是语法糖,底层仍基于原型链。用 extends 实现继承时,子类构造函数中必须显式调用 super(),否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this'

  • super() 必须在使用 this 之前调用,且只能调用一次
  • 父类构造函数需要参数,super(...args) 必须传入对应参数
  • 子类未定义 constructor 时,会自动补上一个隐式 constructor(...args) { super(...args); }
  • 静态方法和 getter/setter 也能被继承,但不会自动绑定 this,需注意调用上下文

手动模拟 extends 的原型链连接

理解 extends 的本质,关键在于三步:设置子类的 prototype.__proto__ 指向父类 prototype;设置子类的 __proto__ 指向父类构造函数;确保子类 constructor 正确指向自身。

  • 等价于:Object.setPrototypeOf(Child.prototype, Parent.prototype)Object.setPrototypeOf(Child, Parent)
  • 漏掉第二步会导致 Child.super 或静态方法调用失败
  • 不推荐手写,但调试继承链断裂(比如 instanceof 失效)时可检查这两处

继承内置类(如 Array、Error)的坑

直接 class MyArray extends Array 在部分旧环境(如 safari 9、node.js Array.isArray(new MyArray()) 可能返回 false

  • 原因:内置类的构造逻辑依赖引擎内部机制,仅靠原型链无法完全复现
  • V8 引擎从 chrome 51+ 开始支持,但 IE 完全不支持
  • 稳妥方案:用 return Object.setPrototypeOf(new Array(), MyArray.prototype) 手动修正实例原型(仅限非严格模式下)
  • 更通用的做法是组合代替继承,例如在类中持有一个 Array 实例并代理方法

如何判断继承关系是否生效

别只信 instanceof,它可能被伪造或因原型链污染失效。应组合验证:

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

  • obj instanceof Child → 检查是否为子类实例
  • Object.getPrototypeOf(obj) === Child.prototype → 精确比对原型
  • Object.getPrototypeOf(Child.prototype) === Parent.prototype → 确认原型链连接正确
  • Child.__proto__ === Parent → 验证静态继承关系(尤其影响 super 调用)

原型链深、多层继承时,最容易被忽略的是静态属性和 super 在箭头函数中的不可用性——箭头函数没有自己的 thissuper,会沿作用域向上找,不是按运行时实例查找。

text=ZqhQzanResources