JavaScript 无原生抽象类,但可通过构造函数中用 new.target 检测并抛错禁止直接实例化,以及在方法体内抛错强制子类重写,来模拟抽象类行为。

JavaScript 本身没有原生的 abstract class 关键字,不像 Java 或 C# 那样能强制子类实现抽象方法。但可以通过约定 + 运行时检查的方式,模拟抽象类的行为规范,达到“定义接口契约、防止直接实例化、要求子类覆盖关键方法”的效果。
用构造函数抛错实现“禁止实例化”
在抽象类的 constructor 中判断是否被直接调用(而非通过 super() 被继承调用),是模拟抽象类最常用且可靠的做法:
- 利用
new.target检测当前构造函数是否为抽象类本身 - 若
new.target === AbstractBase,说明有人试图new AbstractBase(),此时抛出错误
示例:
class Animal {
constructor() {
if (new.target === Animal) {
throw new TypeError('Animal 是抽象类,不能直接实例化');
}
}
<p>speak() {
throw new Error('子类必须实现 speak() 方法');
}
}</p><p>class Dog extends Animal {
speak() {
return '汪汪!';
}
}</p><p>// new Animal(); // ❌ 报错
console.log(new Dog().speak()); // ✅ '汪汪!'
用方法体抛错声明“抽象方法”
抽象方法不提供具体实现,只定义签名和契约。JS 中可通过在父类方法体内直接抛错来提示子类必须重写:
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 不依赖 TypeScript 的
abstract(那是编译期检查) - 运行时触发,对纯 JS 环境友好
- 错误信息应明确指出“必须由子类实现”,便于调试
注意:这类方法仍可被继承,只是调用时会报错——这正是预期行为。
配合 JSDoc 或 TypeScript 提升规范性
虽然 JS 运行时无法强制约束,但可通过工具层补足设计意图表达:
- 在 JSDoc 中标注
@abstract和@virtual,供 IDE 提示和文档生成 - 使用 TypeScript 时,可用
abstract class和abstract method实现编译期检查(最终仍编译为上述 JS 模式) - 团队协作中,配合 ESLint 规则(如
no-useless-constructor或自定义规则)可进一步约束抽象类写法
避免常见误区
有些做法看似“抽象”,实则不可靠或违背语义:
- 仅靠命名(如
AbstractComponent)不加运行时保护 → 无法阻止误用 - 把抽象方法设为
undefined或空函数 → 子类可能静默继承而未察觉缺失实现 - 用
instanceof在子类中反查父类 → 逻辑倒置,破坏封装
真正有效的抽象类模拟,核心就两点:构造器拦截 + 方法体报错。简洁、明确、可执行。

















