搜索
您的当前位置:首页正文

关于Error.captureStackTrace

来源:步旅网

原文:

在一些Node.js程序中,有时会看到Error.captureStackTrace()这一语句,用于处理堆栈信息。该语句的标准定义是什么?如何使用?本文将就这些问题做一些探讨。

标准定义

从字面上来看,captureStackTrace应该是Error构造函数自身的一个方法。因此,很自然的想到从中寻找答案。不幸的是,在标准文档的章节中,并未提及任何有关captureStackTrace的内容。看来,这一语句和语言的运行环境有关,并非由JavaScript标准所定义。

既然JavaScript语言标准中没有定义captureStackTrace,那就只能从Node.js的文档中去寻找答案了。Node.js中,是这样的:

以下是一个最简单的例子:

const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack  // 效果与`new Error().stack`类似

errorObject.stack不同的是,errorObject.stack所返回的字符串的第一行一般遵循ErrorType: message的形式,而使用captureStackTrace所得到的字符串的第一行则一般以targetObject .toString()开头。

除了targetObject, captureStackTrace还接受一个类型为function的可选参数constructorOpt,当传递该参数时,调用栈中所有constructorOpt函数之上的信息(包括constructorOpt函数自身),都会在访问targetObject.stack时被忽略。当需要对终端用户隐藏内部的技术细节时,constructorOpt参数会很有用。比如:

function MyError() {
  Error.captureStackTrace(this, MyError);
}

// 如果没有向captureStackTrace传递MyError参数,则在访问.stack属性时,MyError及其内部信息将会出现在堆栈信息中。当传递MyError参数时,这些信息会被忽略。
new MyError().stack

进一步的探究发现,Error.captureStackTrace()并非Node.js所创造,而是源自(事实上,Node.js的Error类中,所有与stack trace有关的内容均依赖于V8的Stack Trace API)。从语法上来说,Node.js中的Error.captureStackTrace()与V8引擎中所暴露的接口完全一致。

在浏览器领域,除了使用V8引擎的Google Chrome,其它浏览器中不存在Error.captureStackTrace()这一接口。

使用场景

由于Error.captureStackTrace()可以返回调用堆栈信息,因此在自定义Error类的内部经常会使用该函数,用以在error对象上添加合理的stack属性。上文中的MyError类即是一个最简单的例子。

为了不向使用者暴露自定义Error类的内部细节,在自定义Error类内部使用captureStackTrace时,往往会传入constructorOpt参数,其值即为自定义 Error类的构造函数。具体做法有3种:

除了自定义Error类的使用场景,在JavaScript程序中,当需要获知调用堆栈信息时,都可以通过调用Error.captureStackTrace()来实现。以往如果需要获知调用堆栈信息,一般的做法是抛出一个Error对象并立即加以捕捉,通过访问该对象的stack属性来获得调用堆栈。一个简单的例子如下:

try {
  throw new Error();
} catch (e) {
  // e.stack 中包含了堆栈数据,可以进行处理从而忽略不感兴趣的堆栈信息
}

与这种做法相比,可以很明显的看到,使用Error.captureStackTrace()会更简洁、易用,也更优雅;而这,也许就是V8中添加Error.captureStackTrace()的原因。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top