关于Error.captureStackTrace
来源:互联网 发布:linux中rpm是什么意思 编辑:程序博客网 时间:2024/06/06 22:25
原文:关于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种:
Error.captureStackTrace(this, MyError);
将构造函数的变量名作为constructorOpt参数传入。这一做法比较简单、直接,但不利之处也比较明显:代码所要传达的是“忽略当前构造函数及其内部的堆栈调用信息”,而以具体的构造函数作为参数传入使得这一语句缺乏通用性,不利于程序的进一步抽象。Error.captureStackTrace(this, this.constructor);
通过this.constructor
传入constructorOpt参数。与上一种方法相比,这一方式更具通用性。在自定义Error类中使用captureStackTrace时,推荐采用该方法。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()
的原因。
- 关于Error.captureStackTrace
- 关于error
- [VC++] 关于error LNK2001
- 关于fatal error C1063
- 关于exception与error
- 关于error C2664
- 关于Installation error: INSTALL_FAILED_MISSING_SHARED_LIBRARY
- 关于 Installation error: INSTALL_FAILED_MISSING_SHARED_LIBRARY
- 关于error LNK2019
- 关于Runtime Error
- 关于socket error 10054
- 关于Throwable, Error, Exception
- 关于 fatal error C1001: INTERNAL COMPILER ERROR
- 关于 fatal error C1001: INTERNAL COMPILER ERROR
- 关于Error:Error converting bytecode to dex:
- 关于Error:Error converting bytecode to dex:
- 关于on error resume next
- 关于ERROR LNK 2005错误
- 学习与使用 PRINCE2项目管理方法的收益——上海信息化培训中心
- 字符串计数-复杂的动态规划题 解析以及Java代码实现
- fanxuan
- hadoop 学习笔记:mapreduce框架详解
- 微信支付JSAPI模式及退款CodeIgniter集成篇
- 关于Error.captureStackTrace
- CocoPod的安装使用
- 深入JVM类加载器
- 在foreach中使用key($array)
- Twitter的开源自动化测试工具diff
- Android 滑动关闭Activity 示例
- Anaconda包查找,conda自定义本地channel作为python package源进行离线安装,离线创建环境
- Cocos2d-x V3.10项目(cocos2d-x lua) 输出控制台2
- linux程序设计:可重入和线程安全