错误定位是开发中的一项必备的重要能力,咱们来看下在前端开发中v8为咱们提供的Error关键字前端
当像函数同样使用 Error 时 -- 若是没有 new,它将返回一个 Error 对象。因此, 仅仅调用 Error 将产生与经过new 关键字构造 Error 对象的输出相同。webpack
// this:
const x = Error('I was created using a function call!');
// has the same functionality as this:
const y = new Error('I was constructed via the "new" keyword!');
复制代码
除了通用的Error构造函数外,JavaScript还有6个其余类型的错误构造函数web
建立V8时抛出的全部内部错误都将捕获堆栈跟踪。能够经过非标准error.stack属性从JavaScript访问此堆栈跟踪。V8还具备各类钩子,用于控制如何收集和格式化堆栈跟踪,并容许自定义错误也收集堆栈跟踪。本文档概述了V8的JavaScript堆栈跟踪API。api
默认状况下,V8引起的几乎全部错误都具备一个stack属性,该属性保存最顶层的10个堆栈帧,格式为字符串。这是一个彻底格式化的堆栈跟踪的示例: 函数
堆栈跟踪是在建立错误时收集的,而且不管在何处或抛出错误的次数都相同。咱们收集10帧,由于一般它足以有用,但数量很少,会对性能产生明显的负面影响。能够经过设置变量来控制收集多少堆栈帧性能
Error.stackTraceLimit
复制代码
将其设置为0禁用堆栈跟踪收集。任何有限的整数值均可以用做要收集的最大帧数。设置为Infinity表示将收集全部帧。该变量仅影响当前上下文。必须为每一个须要不一样值的上下文显式设置它。ui
注意
Error.stackTraceLimit是一个非标准的api 请勿在生产环境下使用this
用于堆栈错误的堆栈跟踪机制是使用通用堆栈跟踪收集API来实现的,该API也可用于用户脚本spa
Error.captureStackTrace(error, constructorOpt)
复制代码
将堆栈属性添加到给定的error对象,该属性在调用时产生堆栈跟踪captureStackTrace。收集的堆栈跟踪信息Error.captureStackTrace将当即收集,格式化并附加到给定的error对象。3d
可选constructorOpt参数容许您传递函数值。收集堆栈跟踪时,对该函数最顶层调用(包括该调用)上方的全部帧均不包含在堆栈跟踪中。这对于隐藏对用户无用的实现细节颇有用。定义捕获堆栈跟踪的自定义错误的一般方法是:
function MyError() {
Error.captureStackTrace(this, MyError);
// Any other initialization goes here.
}
console.log(new MyError().stack);
复制代码
这样将会忽略堆栈中的函数调用栈信息
因为Error.captureStackTrace()能够返回调用堆栈信息,所以在自定义Error类的内部常常会使用该函数,用以在error对象上添加合理的stack属性。上文中的MyError类便是一个最简单的例子。
为了避免向使用者暴露自定义Error类的内部细节,在自定义Error类内部使用captureStackTrace时,每每会传入constructorOpt参数,其值即为自定义 Error类的构造函数。具体作法有3种:
webpack的错误捕获对象 WebpackError
就是这么干的"use strict";
const inspect = require("util").inspect.custom;
class WebpackError extends Error {
/** * Creates an instance of WebpackError. * @param {string=} message error message */
constructor(message) {
super(message);
this.details = undefined;
this.missing = undefined;
this.origin = undefined;
this.dependencies = undefined;
this.module = undefined;
Error.captureStackTrace(this, this.constructor);
}
[inspect]() {
return this.stack + (this.details ? `\n${this.details}` : "");
}
}
module.exports = WebpackError;
复制代码
除了自定义Error类的使用场景,在JavaScript程序中,当须要获知调用堆栈信息时,均可以经过调用Error.captureStackTrace()来实现。以往若是须要获知调用堆栈信息,通常的作法是抛出一个Error对象并当即加以捕捉,经过访问该对象的stack属性来得到调用堆栈。一个简单的例子以下
try {
throw new Error();
} catch (e) {
// e.stack 中包含了堆栈数据,能够进行处理从而忽略不感兴趣的堆栈信息
}
复制代码
与这种作法相比,能够很明显的看到,使用Error.captureStackTrace()会更简洁、易用,也更优雅;而这,也许就是V8中添加Error.captureStackTrace()的缘由。