JavaScript中用class实现多态的核心是继承+方法重写+动态绑定:基类声明同名接口(如area),子类重写具体实现,通用函数通过基类引用调用,运行时自动绑定实际类型方法。

JavaScript 中用 class 实现多态,核心是“同名方法、不同实现”,再配合统一接口调用。不需要额外库或复杂配置,靠继承 + 方法重写 + 动态绑定就能自然达成。
定义基类并声明公共接口
基类不一定要有具体实现,关键是提供一个可被子类覆盖的契约方法。它让后续调用方知道该调用什么名字的方法。
- 用
class声明父类,方法体可以抛错(表示必须由子类实现),也可以给默认行为 - 方法名就是“接口”——比如
render()、calculate()、save() - 避免在基类里写业务强相关的逻辑,保持抽象性
示例:
class Shape {area() {
throw new Error('子类必须实现 area 方法');
}
}
子类继承并重写方法
每个子类根据自身特性提供具体实现。JavaScript 的方法调用是运行时动态绑定的,调用 obj.area() 时,引擎自动找到该对象实际类型的 area 方法。
- 使用
extends继承基类 - 在子类中定义同名方法,直接覆盖父类版本
- 可选择是否调用
super.xxx()—— 多态不要求必须调用父类,只关注最终行为差异
示例:
class Rectangle extends Shape {constructor(width, height) {
super();
this.width = width;
this.height = height;
}
area() { return this.width * this.height; }
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() { return Math.PI * this.radius ** 2; }
}
编写通用逻辑函数或方法
通用逻辑只依赖基类接口,不关心具体类型。传入任意子类实例,都能正确执行对应实现。
- 函数参数类型标注为基类(开发时语义清晰,TypeScript 中还可校验)
- 内部只调用约定好的方法名,如
shape.area() - 可批量处理:用数组存不同子类实例,遍历调用同一方法
示例:
function printArea(shape) {console.log(`面积是:${shape.area()}`);
}
const rect = new Rectangle(5, 3);
const circle = new Circle(4);
printArea(rect); // 面积是:15
printArea(circle); // 面积是:50.265...
注意 this 和调用上下文一致性
多态生效的前提是方法被“对象调用”,即 obj.method() 形式。如果把方法单独提取出来,this 会丢失,导致多态失效。
- 错误写法:
const fn = obj.area; fn();→ 此时this指向全局或 undefined - 正确写法:
obj.area()或obj.area.bind(obj)或fn.call(obj) - 数组遍历时推荐用箭头函数或显式绑定,避免隐式丢失


















