錯誤定位是開發中的一項必備的重要能力,咱們來看下在前端開發中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()的緣由。