关于Error.captureStackTrace

在一些Node.js顺序中,有时会看到Error.captureStackTrace()这一语句,用于处置惩罚客栈信息。该语句的规范定义是什么?怎样运用?本文迁就这些题目做一些讨论。

规范定义

从字面上来看,captureStackTrace应该是Error组织函数本身的一个要领。因而,很天然的想到从ECMAScript规范文档中寻觅答案。不幸的是,在规范文档的19.5 Error Objects章节中,并未说起任何有关captureStackTrace的内容。看来,这一语句和言语的运转环境有关,并不是由JavaScript规范所定义。

既然JavaScript言语规范中没有定义captureStackTrace,那就只能从Node.js的文档中去寻觅答案了。Node.js中,关于Error.captureStackTrace的形貌是如许的:

Error.captureStackTrace(targetObject[, constructorOpt])
targetObject中增加一个.stack属性。对该属性举行接见时,将以字符串的情势返回Error.captureStackTrace()语句被挪用时的代码位置信息(即:挪用栈汗青)。

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

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所制造,而是源自V8引擎的Stack Trace API(事实上,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种:

  1. Error.captureStackTrace(this, MyError); 将组织函数的变量名作为constructorOpt参数传入。这一做法比较简朴、直接,但不利的地方也比较显著:代码所要转达的是“疏忽当前组织函数内部的客栈挪用信息”,而以详细的组织函数作为参数传入使得这一语句缺少通用性,不利于顺序的进一步笼统。

  2. Error.captureStackTrace(this, this.constructor); 经由过程this.constructor传入constructorOpt参数。与上一种要领比拟,这一体式格局更具通用性。在自定义Error类中运用captureStackTrace时,引荐采纳该要领。

  3. Error.captureStackTrace(this, arguments.callee);经由过程arguments.callee将“当前函数”作为constructorOpt参数传入。不过,因为ES5的strict形式中禁用了arguments.callee,因而不发起运用该写法。

除了自定义Error类的运用场景,在JavaScript顺序中,当须要获知挪用客栈信息时,都能够经由过程挪用Error.captureStackTrace()来完成。以往假如须要获知挪用客栈信息,平常的做法是抛出一个Error对象并马上加以捕获,经由过程接见该对象的stack属性来取得挪用客栈。一个简朴的例子以下:

try {
  throw new Error();
} catch (e) {
  // e.stack 中包含了客栈数据,能够举行处置惩罚从而疏忽不感兴趣的客栈信息
}

与这类做法比拟,能够很显著的看到,运用Error.captureStackTrace()会更简约、易用,也更文雅;而这,或许就是V8中增加Error.captureStackTrace()的缘由。

链接:http://blog.shaochuancs.com/about-error-capturestacktrace/

    原文作者:shaochuancs
    原文地址: https://segmentfault.com/a/1190000007076507
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞