JavaScript 继承实现:混合构造函数与原型链详解
本文通过 Polygon、Triangle 和 Rectangle 类的示例,详解 JavaScript 中基于混合构造函数与原型链的继承实现。文章解析了子类如何覆盖父类属性与方法,并深入探讨动态原型法在继承中的局限性及正确用法,帮助开发者理解原型对象绑定的关键细节。
创建基类
1. 创建基类
首先分析 Polygon 类的构成。该类必须包含表示边数的整数属性 sides。此外,为了计算面积,还需定义一个返回面积的方法 getArea()。图 4-3 展示了该类的 UML 结构。

图 4-3
在 UML 图中,属性位于类名下方的单元格内,由属性名和类型组成;方法位于属性下方,标明方法名及返回值类型。
在 ECMAScript 中,该类可定义如下:

需注意,此时的 Polygon 类尚不完整,无法直接使用。方法 getArea() 仅返回 0,作为占位符供子类覆盖。
创建子类
2. 创建子类
接下来构建 Triangle 类。由于三角形固定有三条边,该类需覆盖父类的 sides 属性并设为 3。同时,需实现 getArea() 方法,依据公式 1/2×底×高计算面积。为此,需新增 base 和 height 属性以接收输入值。图 4-4 展示了 Triangle 类的 UML 表示。
该图仅列出 Triangle 新增的属性及被覆盖的方法。若未覆盖 getArea(),该方法将视为从 Polygon 继承而来。完整的 UML 图(图 4-5)展示了 Polygon 与 Triangle 之间的继承关系。

在 UML 表示中,除非方法被覆盖(ECMAScript 不支持重载),否则不会重复显示继承的属性和方法。
Triangle 类的代码如下:


注意,尽管 Polygon 构造函数仅接受 sides 参数,Triangle 构造函数却接受 base 和 height 两个参数。由于边数固定为 3 且不应由开发者修改,代码通过对象冒充将 3 传递给 Polygon 构造函数,随后将 base 和 height 赋值给相应属性。
利用原型链继承后,Triangle 覆盖 getArea() 方法,提供针对三角形面积定制的计算逻辑。
最后一个类是 Rectangle,同样继承自 Polygon。矩形有四条边,面积通过长度乘以宽度计算,因此需新增 length 和 width 属性。在 UML 图中,Rectangle 类与 Triangle 类并列,二者超类均为 Polygon(如图 4-6 所示)。

图 4-6
Rectangle 的 ECMAScript 代码如下:
![]()
![]()

注意,Rectangle 构造函数不接收 sides 参数,而是直接将常量 4 传递给 Polygon 构造函数。与 Triangle 类似,Rectangle 引入两个新属性作为构造函数参数,并覆盖 getArea() 方法。
测试代码
3. 测试代码
运行以下代码以测试上述示例:

该代码创建一个底为 12、高为 4 的三角形,以及一个长为 22、宽为 10 的矩形。随后输出各形状的边数及面积,验证 sides 属性赋值正确且 getArea() 返回值准确。预期三角形面积为 24,矩形面积为 220。
动态原型法的局限性
4. 采用动态原型方法如何?
前述示例使用混合构造函数/原型方式展示继承,那么是否可以使用动态原型法实现继承?答案是否定的。
动态原型法无法用于继承的原因在于 prototype 对象的特性。参考以下代码(该代码有误,但值得分析):
![]()


上述代码展示了使用动态原型定义的 Polygon 和 Triangle 类。错误在于设置 Triangle.prototype 属性的代码段。虽然逻辑位置正确,但功能上无效。技术层面而言,在代码执行前,对象已实例化并与原始 prototype 对象关联。尽管极晚绑定可使原型修改生效,但替换 prototype 对象对已存在的实例无影响。仅新创建的实例会反映此改变,导致首个实例失效。
要正确使用动态原型实现继承,必须在构造函数外部赋予新的 prototype 对象,如下所示:

该代码有效,因为在任何对象实例化前已对 prototype 赋值。然而,这意味着无法将代码完整封装在构造函数内,违背了动态原型法的主旨。
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
