JavaScript 中的 Error 对象可被继承扩展以创建语义清晰的自定义错误类,需在子类构造函数中调用 super(message)、显式设置 this.name,并根据环境选择 Error.captureStackTrace 或手动修正 stack 以确保堆栈可靠性。

JavaScript 中的 Error 对象可以被继承和扩展,用于构建语义清晰、便于调试和分类处理的自定义错误类型。关键在于正确使用 class 继承 Error,并在构造函数中调用 super() 同时手动设置 this.name 和 this.stack(尤其在旧环境或需精确控制时)。
继承 Error 构建自定义错误类
ES6 起支持类继承原生内置对象(如 Error),但需注意:仅靠 super(message) 不足以保证所有环境下的 stack 正确性。推荐显式绑定 this.name 并利用 Error.captureStackTrace(Node.js)或手动补全 stack(浏览器兼容写法)。
- 必须在子类构造函数中调用
super(message),否则会报错 -
this.name应设为类名字符串(如"ValidationError"),否则instanceof成立但error.name仍为"Error" - 若需添加额外属性(如
code、details),直接赋值到this即可,不影响原型链
确保 stack 可靠性的两种常用方式
在浏览器中,new Error().stack 通常自动包含构造位置;但继承后可能丢失或不准确。可通过以下方式增强可靠性:
-
推荐(现代环境): 使用
super(message)+ 显式赋值this.name,多数主流浏览器和 Node.js(v10+)已能正确生成stack -
兼容写法(需精确控制): 在构造函数末尾执行
this.stack = new Error().stack.replace(/^Error/, this.name),强制修正堆栈头
抛出与捕获的实用逻辑
抛出自定义错误与抛出普通 Error 完全一致,但捕获时建议用 instanceof 区分类型,而非依赖 error.name 字符串匹配(易受篡改)。
立即学习“Java免费学习笔记(深入)”;
- 抛出:
throw new ValidationError("Email format invalid", { field: "email" }); - 捕获:
if (err instanceof ValidationError) { ... }比err.name === "ValidationError"更安全 - 可配合
try/catch外层统一处理,或在 Promise 链中用.catch()分类响应
常见误区与注意事项
避免因细节疏忽导致错误不可识别或调试困难:
- 忘记设置
this.name→ 错误实例name仍为"Error",影响日志分类和监控 - 在构造函数中未调用
super()→ 直接报ReferenceError: Must call super constructor - 将自定义错误类定义在箭头函数或非 class 语法中 → 无法被
instanceof正确识别 - 在 TypeScript 中未声明额外属性类型 → 编译期无提示,运行时访问
err.code可能报undefined








