Error.captureStackTrace(targetObject[, constructorOpt)
作用
在 targetObject
上创建一个 .stack
属性,将以字符串的形式返回 Error.captureStackTrace()
语句被调用时的代码位置信息(即:调用栈历史)。
特点
只能在 Node.js 和 Chrome 浏览器中使用。
与 new Error().stack
类似,后者使用范围更广,两者都能使用的情况下,优先使用 Error.captureStackTrace
,理由是:
- 无需 new 一个新的 Error 对象,节省内存空间,同时代码上也会更加优雅;
- 如果需要忽略部分堆栈信息,使用 Error.captureStackTrace 会更加方便,无需手工操作;
- 如果使用
Error.captureStackTrace
,则对于堆栈信息的格式化工作会被延迟至访问targetObj.stack
时进行,如果targetObject.stack
未被访问,则堆栈信息的格式化工作会被省略,从而节省计算资源。
constructorOpt 参数
为了不向使用者暴露自定义Error类的内部细节,在自定义Error类内部使用 captureStackTrace
时,往往会传入 constructorOpt
参数,其值即为自定义 Error类的构造函数。我们用个例子来说一说这个参数的作用:
class CError() {
constructor(type, detail) {
Error.captureStackTrace(this, this.constructor);
}
//类的其他操作,项目不同各不相同
...
}
我创建了一个 CError 的自定义错误类,现在产生了一个注册用户时用户名已存在的 error,在没设 constructorOpt
属性, targetObj.stack
的调用栈历史是这样的:
Error.captureStackTrace(this)
"CError: 用户名已存在
at new CError (/Users/zyf/myStudy/demo/chatroom/utils/server/Error.js:40:11)
at register (/Users/zyf/myStudy/demo/chatroom/server/controller/user.js:9:23)
at process._tickCallback (internal/process/next_tick.js:68:7)"
设了 constructorOpt
属性,是这样的:
"CError: 用户名已存在
at register (/Users/zyf/myStudy/demo/chatroom/server/controller/user.js:9:23)
at process._tickCallback (internal/process/next_tick.js:68:7)"
设了 constructorOpt
属性,就会隐藏掉 CError
内的内部调用信息。
设置属性的方法随构造函数的不同,大致分为2类:
1.构造函数
Error.captureStackTrace(this, MyError);
将构造函数的变量名作为 constructorOpt
参数传入。
function CError() {
Error.captureStackTrace(this, CError);
}
2.class
Error.captureStackTrace(this, this.constructor);
通过this.constructor
传入constructorOpt
参数。
class CError() {
constructor() {
Error.captureStackTrace(this, this.constructor);
}
}
其实还有一种在构造函数中将
arguments.callee
作为constructorOpt
参数传入,因为已经不推荐使用arguments.callee
了,所以这种方法也不推荐使用。