關於JS中自定義錯誤類型的一些建議
在開發前端項目,調試過程中,經常能看到一些拋出異常的錯誤提示。這些錯誤提示的拋出,意味着代碼運行的中止。
爲什麼我們需要自定義自己的錯誤類型呢
很多做前端可能很少會接觸自定義錯誤類型,貌似挺高深,其實不然。 也就是在檢測到異常時,拋出錯誤而已。
檢測異常? 拋出錯誤? 怎麼檢測法,挺高深,怎麼拋出法,好像都有點嚇人。
說點人話,檢測無非就if else
拋出,無非是執行某個拋出語法罷了throw <ERR>
。
拋出異常,挺嚇人的,普通用戶看着也嚇人,爲啥不使用友好一點的,比如if+彈窗提示呢。
看應用場合。如果你開發的一個半成品,比如某個JS庫,某個框架,那麼很多時候,爲了防止二次開發時出現錯誤,必須強制把錯誤拋出,避免引起進一步的錯誤。
當然,有時,我們希望拋出的錯誤別太嚇人,人性化一點,怎麼辦呢?可以用try + catch
進行捕獲錯誤類型。
如何定義自定錯誤類型呢
ES5中定義
function MyError(message) {
// 實例化自定義錯誤時所傳的錯誤信息參數
this.message = message
// name 指明該錯誤類型(同時在控制檯所打印的錯誤類型即由此字段指明),不指明默認爲Error。
this.name = 'MyError'
// 捕獲到當前執行環境的堆棧追蹤信息,爲自定義錯誤實例添加 `stack` 字段進行保存,
// 第二個參數的含義爲:堆棧追蹤只會展示到`MyError`這個函數(即自定義錯誤的構造函數)被調用之前。
Error.captureStackTrace(this, MyError)
}
// 原型鏈繼承
MyError.prototype = new Error
// 在自定義錯誤的原型上添加構造器函數爲CustomError,
// 若不添加構造器,當獲取自定義錯誤的構造器時,獲取的是上一步`new Error`實例的原型的構造器,即`Error`構造函數
MyError.prototype.constructor = MyError
ES6中定義
class MyErrorextends Error {
constructor (message) {
super(message)
this.name = 'MyError',
// 這一步可不寫,默認會保存堆棧追蹤信息到自定義錯誤構造函數之前,
// 而如果寫成 `Error.captureStackTrace(this)` 則自定義錯誤的構造函數也會被保存到堆棧追蹤信息
Error.captureStackTrace(this, this.constructor)
}
}
如何使用
關鍵就是執行throw new MyError('some error message')
就能實現拋出錯誤
function mythrow() {
// 這就是拋出異常
throw new CustomError('something bad happened!')
}
// 執行拋出異常
mythrow()
這樣程序將終止,並拋出異常。
前面說的,可以人性化一點使用try + catch
,怎麼做呢
try {
// 一些代碼...
if(a==b) mythrow() // 這叫異常檢測哦
} catch(err) {
console.log('Capture the error:')
console.log(err.stack) // 打印堆棧追蹤信息
console.log(err instanceof CustomError, err instanceof Error) // 錯誤是否爲(或繼承自)CustomError 和 Error 類型
console.log(err.constructor.name) // 自定義錯誤的構造器名稱
}
當然,可以使用 console.warn, console.error 打印不同級別的顯示信息