javascript无原生抽象类,可通过构造函数检查子类是否重写方法、用symbol标记抽象方法,或结合typescript的abstract关键字实现编译期强制约束。

JavaScript 本身没有原生的抽象类语法,但可以通过抛出错误的方式在运行时强制子类实现特定方法。
在构造函数中检查子类是否实现了关键方法
这是最常用、最直接的做法:在抽象类的 constructor 中,检查 this 上是否存在某个方法(注意不能用 typeof this.method === 'function' 简单判断,因为原型链上的方法也会被继承)。更稳妥的方式是检查该方法是否在实例自身上定义(即不是从原型继承来的):
class Animal {
constructor() {
// 检查子类是否在实例上定义了 speak 方法
if (this.constructor === Animal) {
throw new Error('Animal 是抽象类,不能直接实例化');
}
if (typeof this.speak !== 'function' || this.speak === Animal.prototype.speak) {
throw new Error('子类必须重写 speak 方法');
}
}
speak() {
// 占位实现,仅用于检测是否被覆盖
throw new Error('speak 方法未被子类实现');
}
}
class Dog extends Animal {
speak() {
return 'Woof!';
}
}
// ✅ 正常
const dog = new Dog();
// ❌ 报错:子类必须重写 speak 方法
class Cat extends Animal {}
// new Cat(); // 抛出错误
用 Symbol 或私有字段辅助标记抽象方法(增强可读性)
为避免子类意外覆盖父类占位方法,可用 Symbol 或 #privateField 做标识,让抽象方法更“显性”:
const ABSTRACT_METHOD = Symbol('abstract method');
class Shape {
constructor() {
if (this.constructor === Shape) {
throw new Error('Shape 是抽象类');
}
if (this.area === Shape.prototype.area) {
throw new Error(`子类必须实现 ${ABSTRACT_METHOD.description}`);
}
}
area() {
return 0; // 占位,实际不会被调用
}
}
配合 TypeScript 实现编译期检查(推荐工程实践)
纯 JavaScript 只能在运行时报错;若项目使用 TypeScript,可真正获得编译期约束:
abstract class Animal {
abstract speak(): string; // ✅ 编译器强制子类实现
move() {
console.log('Moving...');
}
}
class Bird extends Animal {
speak() { // ✅ 必须实现,否则 TS 编译失败
return 'Chirp';
}
}
TypeScript 的 abstract 关键字不会生成运行时代码,但它能提前捕获遗漏,大幅提升开发体验和代码健壮性。
小结:JS 中模拟抽象类的关键点
- 用 constructor 判断 this.constructor === BaseClass 阻止抽象类被直接实例化
- 通过 对比 this.method === Base.prototype.method 检测方法是否被子类重写
- 提供无实际逻辑的占位方法(抛错或返回默认值),仅用于检测目的
- 生产环境建议搭配 TypeScript,获得静态类型层面的抽象约束
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











