关于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相关推荐
- node.js Web应用框架Express入门指南
node.js Web应用框架Express入门指南 作者: 字体:[增加 减小] 类型:转载 时间:2014-05-28 我要评论 这篇文章主要介绍了node.js Web应用框架Express入门 ...
- 你不知道的JavaScript错误和调用栈常识
大多数工程师可能并没留意过 JS 中错误对象.错误堆栈的细节,即使他们每天的日常工作会面临不少的报错,部分同学甚至在 console 的错误面前一脸懵逼,不知道从何开始排查,如果你对本文讲解的内容有系 ...
- Restful API 中的错误处理方案
简介 随着移动开发和前端开发的崛起,越来越多的 Web 后端应用都倾向于实现 Restful API. Restful API 是一个简单易用的前后端分离方案,它只需要对客户端请求进行处理,然后返回结 ...
- js 弹出层的点击事件影响到底层的点击事件_聊一聊 Node.js 错误处理
个人博客:https://blog.skrskrskrskr.com 错误分类 软件程序中,我们可以将错误大致分为外部错误和内部错误两大类. 外部错误是正确编写的程序在运行时产生的错误.它并不是程序本 ...
- JavaScript错误处理和堆栈追踪浅析
有时我们会忽略错误处理和堆栈追踪的一些细节, 但是这些细节对于写与测试或错误处理相关的库来说是非常有用的. 例如这周, 对于 Chai 就有一个非常棒的PR, 该PR极大地改善了我们处理堆栈的方式, ...
- 添加谷歌翻译到你的网站
网站懒得做i18n? 不如直接谷歌翻译 特性 使用translate.google.cn资源,大陆地区也能使用 自动判断浏览器语言 支持Google 翻译支持的所有语言 隐藏谷歌翻译的样式,更美观 i ...
- vue-cli 基本原理
编写一个简单的 vue-cli 就可以轻松明白原理是怎么运行的了.理解 cli 的插件形式开发,并且可以选择配置,下载不同的模板内容. const inquirer = require('inquir ...
- JavaScript数据类型、引用类型、操作符、语句
目录 数据类型 PS 深/浅拷贝 Array.from 浅 Object.assign 浅 扩展运算符 浅 P.PS 可枚举属性 判断属性 获取属性 附录typeOf 2.0 Undefined 2. ...
- JavaScript Errors 指南
英文:mknichel 译文:Jocs https://github.com/Jocs/jocs.github.io/issues/1 在README文件中包含了这么多年我对JavaScript er ...
最新文章
- plotly同时可视化表格与图(plotly Table and Chart )
- WLST - Presentation Transcript
- php实现 明明的随机数
- Vue2+VueRouter2+webpack 构建项目实战(四)接通api,先渲染个列表
- python的subprocess模块执行shell命令
- 花书+吴恩达深度学习(二二)自编码器(欠完备,DAE,CAE,PSD)
- 水晶报表 动态控制图片显示 Changing pictures dynamically in Crystal Report
- vijos 1066 树状数组
- 合并的表格怎么加横线_怎么在表格中加一横线
- 清华大学的计算机课程表,清华大学计算机专业课程表
- 如何制作刷爆朋友圈的H5
- 光纤猫下接路由器的设置教程
- VMware临时文件清理
- Python之ARP协议探测MAC地址
- 前端css基础知识点之PC端项目-规范
- 【全志T113-S3_100ask】15-2 linux系统gpio模拟spi驱动屏幕——ILI9341
- 畅想物联网安全未来,几维安全让万物互联更安全
- 【小知识】字符编码笔记:ASCII,Unicode 和 UTF-8
- Squirrel and chestnut CodeChef - SQUIRREL
- lora网关软件设计_LoRa 物联网集成开发套件
热门文章
- 神秘使者到Java帝国传道协程,竟被轰了出去
- 攻克机器学习硕士学位,我的那些年与必备技能!
- 涨知识!Google 黑客常用搜索语句一览 | 原力计划
- 银泰抛弃传统数据库转投阿里云PolarDB 投入产出比增长2倍以上
- 微软 CEO 萨提亚·纳德拉:不要重复造轮子,提升技术强密度
- 华为 P40 “一胞三胎”,最贵价 10854 元
- 用 3 只“鸽子”,告诉你闪电网络如何改变加密消息传递方式!
- Firefox 差点就赢了第二次浏览器大战!
- Python 的一个脚本错误可能会废掉 150 多个项目!
- 为什么你必须了解云原生?!