異常處理
異常處理可以使程序在流程上更加完善。
在 JavaScript 中可以使用 throw
拋出異常,使用 try ... catch
捕獲錯誤。
1. throw
throw 語句用來拋出一個用戶自定義的異常。(MDN)
throw 用于拋出一個異常,這種異常通常是程序出現了不符合預期的錯誤。
alert('出錯前');
throw '發生了一個錯誤!';
alert('出錯后');
當出現 throw
時,程序將會中斷執行。
如果 throw
發生在 try ... catch
中,則會執行 catch
中的代碼塊,同時將異常信息帶給 catch。
2. try … catch
try…catch 語句標記要嘗試的語句塊,并指定一個出現異常時拋出的響應。
try ... catch
可以用于捕獲異常,當出現 throw 時,會結束 try
內的代碼執行,直接進入到 catch
,執行 catch
內的代碼塊。
try {
alert('出錯前');
throw '發生了一個錯誤!';
alert('出錯后');
} catch (e) { // e 是錯誤信息,名字隨意,符合變量命名規范就行
alert('出錯了!錯誤是:' + e);
}
需要注意的是,以前 catch 后面的錯誤參數是必須接收的,否則會報錯。
但 ES2019 中有一個提案,可以選擇性的提供給 catch 參數,所以最新的 chrome 不傳遞錯誤參數也是可以的。
try {
alert('出錯前');
throw '發生了一個錯誤!';
alert('出錯后');
} catch {
alert('出錯了!');
}
由于是比較新的提案,所以建議沒有工具參與代碼編譯時,還是寫上錯誤參數的接收,避免因瀏覽器兼容性造成的問題。
在 try 后面還可以跟 finally
部分,即無論 try 中的代碼塊是否拋出錯誤,都會執行 finally
代碼塊。
try {
alert('開始請求數據,loading 顯示');
throw '沒有網絡';
alert('請求結果是:..編不下去了,反正到不了這里');
} catch (e) {
alert('出現錯誤:' + e);
} finally {
alert('關閉 loading');
}
3. 可以寫條件的 catch 語句
部分文獻記載了如下格式的 try … catch 語法。
try {
throw 'error';
} catch (e if e instanceof TypeError) {
console.log('TypeError');
} catch (e if e instanceof ReferenceError) {
console.log('ReferenceError');
} catch (e) {
console.log(e);
}
但目前主流瀏覽器基本都無法正常運行這種語法的 try … catch 語句,所以不要使用。
如果有類似的需求,可以使用 if 來代替。
try {
throw 'error';
} catch (e) {
if (e instanceof TypeError) {
console.log('TypeError');
} else if (e instanceof ReferenceError) {
console.log('ReferenceError');
} else {
console.log(e);
}
}
4. Error 對象
通過 Error 的構造器可以創建一個錯誤對象。當運行時錯誤產生時,Error的實例對象會被拋出。Error 對象也可用于用戶自定義的異常的基礎對象。(MDN)
通常在使用 throw 拋出異常時,會拋出一個 Error
對象的實例。
try {
throw new Error('主動拋出一個錯誤');
} catch (e) {
console.error(e);
}
和大部分內置對象一樣,Error 實例也可以不使用 new
關鍵字創建。
try {
throw Error('主動拋出一個錯誤');
} catch (e) {
console.error(e);
}
拋出 Error 實例,可以得到出現異常的文件和對應的行號。
除了 Error
,還有幾種預定義好語義的異常對象。
5. 其他異常對象
URIError
表示以一種錯誤的方式使用全局URI處理函數而產生的錯誤;TypeError
值的類型非預期類型時發生的錯誤;SyntaxError
嘗試解析語法上不合法的代碼的錯誤;ReferenceError
當一個不存在的變量被引用時發生的錯誤;RangeError
當一個值不在其所允許的范圍或者集合中拋出的異常;InternalError
表示出現在 JavaScript 引擎內部的錯誤。非標準對象,不建議使用;EvalError
本對象代表了一個關于 eval 函數的錯誤.此異常不再會被 JavaScript 拋出,但是EvalError對象仍然保持兼容性。
這些異常對象的使用和 Error
幾乎一致。
瀏覽器碰到對應的異常,也會拋出。
try {
console.log(notDefinedVariable);
} catch (e) {
console.error(e);
}
因為 notDefinedVariable
并沒有定義,所以瀏覽器會拋出 ReferenceError
異常,同時提示變量沒有定義。
6. 小結
完整的產品業務邏輯流程,基本都要 try ... catch
參與控制,因為出現異常時,還要有對應的動作,如網絡請求異常,則提示用戶重試,或主動進行超時重新請求操作。