摘要:在一些程序中,有時會看到這一語句,用于處理堆棧信息。為了不向使用者暴露自定義類的內部細節,在自定義類內部使用時,往往會傳入參數,其值即為自定義類的構造函數。
在一些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()的原因。
鏈接:http://blog.shaochuancs.com/about-error-capturestacktrace/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80599.html
摘要:錯誤處理在開發和調試過程中都顯得尤為重要。跟全局函數有關的錯誤,在之后已經不再出現了內部錯誤。由引擎拋出的錯誤范圍錯誤。事件任何沒有的錯誤都會觸發對象的事件。事件可以接收三個參數錯誤消息錯誤所在的和行號。 錯誤處理在開發和調試過程中都顯得尤為重要。有些沒有進行錯誤處理的應用,直接就將瀏覽器的錯誤展示給了用戶,極大的降低了用戶體驗。比如有些很 low 的網站,打開某些頁面就直接彈出 ob...
摘要:調用堆棧實際上就是一個方法列表,按調用順序保存所有在運行期被調用的方法。調用堆棧會將當前正在執行的函數調用壓入堆棧,一旦函數調用結束,又會將它移出堆棧。 原文 JavaScript Errors and Stack Traces in Depth 調用棧Call Stack是如何工作的 棧是一個后進先出LIFO (Last in,First out)的數據結構。調用堆棧實際上就是一個方...
摘要:并不自帶,需要引入庫運行日志文件,此時在目錄下就生成了今天的日志歡迎訪問我的博客 node項目中的錯誤處理 node中Error對象的使用 使用captureStackTrace方法加入自帶的錯誤信息 // Error對象自帶的屬性 Error.captureStackTrace // 如何使用captureStackTrace var obj = { message: so...
摘要:繼承方法原型鏈繼承父類型子類型子類型的原型為父類型的一個實例對象這種繼承方式把設置直接設置為對象子類就可以通過原型鏈訪問父級所有的屬性和方法了。但是缺點很明顯,在創建子類的時候會調用調用兩次父類的構造函數。 起因 最近在使用node-jsonwebtoken中發現了下面這個代碼,感覺挺好看,于是就打算探索一些相關代碼: showImg(https://segmentfault.com/...
摘要:錯誤上報機制發送數據因為請求本身也有可能會發生異常,而且有可能會引發跨域問題,一般情況下更推薦使用動態創建標簽的形式進行上報。 js錯誤捕獲 js錯誤的實質,也是發出一個事件,處理他 error實例對象 對象屬性 message:錯誤提示信息 name:錯誤名稱(非標準屬性)宿主環境賦予 stack:錯誤的堆棧(非標準屬性)宿主環境賦予 對象類型(7種) Synt...
閱讀 3098·2023-04-26 01:58
閱讀 951·2021-11-24 09:38
閱讀 3285·2021-09-03 10:29
閱讀 713·2021-08-21 14:10
閱讀 1488·2019-08-30 15:44
閱讀 3085·2019-08-30 14:10
閱讀 3211·2019-08-29 16:32
閱讀 1476·2019-08-29 12:48