JavaScript 中的继承是基于原型链(Prototype Chain)实现的,对象通过
[[Prototype]]链接到另一个对象,实现属性和方法的复用。
解决的核心痛点:如何在不破坏封装性的前提下复用代码?继承提供了一种 “is-a” 关系,让子类复用父类的实现。
核心命题
- JavaScript 的继承是原型链继承
- 原理:JavaScript 传统上使用原型链实现继承,对象的
[[Prototype]]指向父对象,查找属性时沿链向上;ES6 class 只是原型继承的语法糖
- 原理:JavaScript 传统上使用原型链实现继承,对象的
- ES6 class 继承只是原型链的语法糖
- 原理:
class关键字只是基于原型继承的语法糖,本质上还是通过prototype对象实现的
- 原理:
运行机制
- 原型链查找:访问属性时,先在自身查找,找不到则沿
[[Prototype]]向上查找 - 方法复用:父类的方法只需定义一次,所有子类实例共享
- 属性遮蔽:子类属性会覆盖父类同名属性
关键区别
| 维度 | 原型链继承 | 类继承(Java/C++) |
|---|---|---|
| 实现方式 | [[Prototype]] 链接 | extends 关键字 |
| 继承类型 | 单继承(多重继承需 mixin) | 支持多重继承 |
| 时机 | 动态(运行时可修改) | 静态(编译时确定) |
应用场景
- ✅ 适用场景
- 代码复用:多个对象共享相同的方法或属性
- 类型体系:建立对象类型层次结构
- 插件扩展:在保持父对象完整性的同时扩展功能
- ⛔ 误用
- 原型链过长:链过长会影响查找性能
- 循环引用:避免原型链形成环
知识图谱
参考延伸
- MDN:继承与原型链
- 《你不知道的 JavaScript》上卷:原型