Javascript錯誤處理

毋庸置疑的是,在程序設計中,錯誤處理是很重要的一個環(huán)節(jié)。不管水平多高的軟件開發(fā)人員,都或多或少地難以避免寫出邏輯不是特別嚴謹?shù)拇a。另一方面來說,當我們的寫的代碼中帶有錯誤處理的邏輯時,當出現(xiàn)了錯誤時可以及時通知到用戶,這會帶來用戶體驗上的提升。作為開發(fā)人員,我們要知道如何處理Javascript錯誤。

try-catch語句

在Javascript中,通過try-catch語句來實現(xiàn)異常的處理。該語句作為標準的一部分,其語法規(guī)則如下:

`try {`

`.....`

`} catch (error) {`

`.....`

`}`

在使用時,我們可以將所有可能會拋出錯誤的代碼放在try語句塊中,在catch語句塊中是對錯誤的處理。 當try塊中出現(xiàn)錯誤時,就會退出try塊,從而執(zhí)行catch中的錯誤處理代碼。在上面的語法規(guī)則中,可以發(fā)現(xiàn)catch接受一個錯誤對象error.在error中主要存在兩個屬性:name屬性 和 message屬性。

這里要注意的是,如果在try塊中執(zhí)行代碼時遇到錯誤,出現(xiàn)錯誤的語句后面的語句都不會再被執(zhí)行。如果想要不管有沒有遇到錯誤都執(zhí)行一些語句,那么可以把這些語句放在finally子句中。

finally子句

標準中還引入了另一個子句:finally語句。它是搭配try-catch語句的一個可選的語句。但是,一旦使用,無論try-catch語句塊中包含什么代碼,finally中的代碼都會執(zhí)行。

  • try中的代碼正常執(zhí)行,finally中的語句正常執(zhí)行。

  • try中的代碼執(zhí)行過程中出錯從而執(zhí)行catch語句, finally中的語句正常執(zhí)行。

  • try塊中存在return語句,finally中的代碼仍然正常執(zhí)行。(只要包含finally語句,try-catch中的return都將被忽略!

Javascript中的錯誤類型

  • Error

基類型。其他的錯誤類型均繼承自它。這個基類型的主要目的是供開發(fā)人員拋出自定義錯誤。

  • EvalError

由于使用eval函數(shù)引發(fā)的錯誤。

  • SyntaxError

語法錯誤。

image
  • TypeError

類型錯誤。當錯誤使用變量或對象時,會拋出該錯誤。

image
  • ReferenceError

引用錯誤。當引用一個不存在的對象或不存在的變量時會發(fā)生該錯誤。

image
  • RangeError

范圍錯誤。數(shù)值超出范圍時觸發(fā)。比如一個數(shù)組元素的取值為負值,就會拋出該錯誤。

image
  • URIError

合理使用try-catch

當我們使用try-catch處理錯誤之后,瀏覽器就不會再對錯誤進行處理。瀏覽器如何處理錯誤,下面會講到。使用try-catch的情況一般為try塊中的代碼是我們無法控制的,也就是說我們不能確定它會不會出現(xiàn)錯誤,如果出現(xiàn)錯誤,是哪種錯誤。 比如,我們使用了第三方庫或是別人寫的工具函數(shù)之類的,我們無法確定這些函數(shù)會不會有意無意地拋出一些錯誤。因此,在這種情況下使用try-catch來對使用的函數(shù)進行包裹,從而對可能出現(xiàn)的錯誤進行處理。

當我們明確知道代碼會發(fā)生錯誤時,再使用try-catch就不是太合適了。而且,在上面我們也介紹了,Error對象是基類型,主要目的是用來拋出自定義錯誤。

Throw

在JS中,我們通過throw來拋出錯誤。而且,throw的使用情況為: 我們明確知道代碼會發(fā)生錯誤的情況。 比如:

`function  test(arr)  {`

`// 此處應該傳進來一個數(shù)組`

`alert(arr[0])`

`}`

對于這種情況,我們需要對參數(shù)arr進行一個處理。可以發(fā)現(xiàn),我們在test函數(shù)里面,默認出進來的參數(shù)為數(shù)組,從而直接進行數(shù)組操作。但是如果傳進來的不是數(shù)組呢? 肯定會出錯。這就需要我們對參數(shù)進行一個判斷,如果不是數(shù)組,則拋出一個錯誤。

`function  test(arr) {`

 `if (!Array.isArray(arr))`

 `throw  new  Error("test(): arr must be an Array instance ")`

`    alert(arr[0])`

`}`
  • 通過throw拋出的錯誤會被外層的catch語句塊所捕獲。如果沒有catch語句塊,則會被瀏覽器捕獲,從而在瀏覽器控制臺可以看到錯誤信息。

這里要注意,拋出的錯誤類型不一定非要是Error,也可以是上面所說的任何類型,甚至是自定義錯誤類型。

對于自定義錯誤類型,可以通過繼承自Error來實現(xiàn)。

如何自定義錯誤類型

其實,我們可以不一定通過繼承Error來實現(xiàn)自定義錯誤類型。

image
  • 使用繼承的好處就是可以通過obj instanceof Error 來識別這個一個錯誤對象。
`class  MyError  extends  Error  {`

 `constructor(message) {`

 `super(message);`

 `this.name = "MyError"`

`}`

`}`

這樣的話,我們就可以在catch中對其進行判斷。

`try {`

`.....`

`} catch (error) {`

 `if (error instanceof  Error) {`

`    .................`

`    }`

`}`
`// 更多詳細的內(nèi)容建議參考: https://zh.javascript.info/custom-errors`

我們還可以在catch中通過throw來拋出錯誤。這種情況發(fā)生在: 我們在catch中對收到的error做一個篩選,如果是特定的錯誤,對其進行處理。否則,表明出現(xiàn)了未知錯誤,將它繼續(xù)拋出去。

錯誤對象(error)

上面說了,catch語句會收到關于錯誤信息的error對象。該對象主要有以下兩種屬性:

  • Name 錯誤類型名稱

  • Message 關于error的描述

還有其他的一些屬性,根據(jù)瀏覽器的不同而有所不同。不過,最廣泛使用和支持的是:

  • Stack 當前調用棧信息

Throw 與try-catch的說明

捕獲錯誤是為了防止瀏覽器對其進行默認處理。拋出錯誤是為了提供錯誤發(fā)生的具體原因信息。

error事件

當代碼中出現(xiàn)錯誤,而未使用try-catch進行捕獲處理的情況下,瀏覽器會捕獲到該錯誤。即: 任何沒有通過try-catch處理的錯誤都會觸發(fā)window的error事件。在任何瀏覽器中,onerror事件處理程序都不會接受一個event對象,相反,接受的是三個參數(shù): message(錯誤信息), url(錯誤所在的URL) 和 line(行號)。

`window.onerror = function ( message, url, line ) {`

`........`

`}`

這里要注意的是,onerror事件只能通過上面的方式添加事件處理程序,不可以通過DOM2的addEventListener。

在事件處理程序中,通過return false可以阻止瀏覽器報告錯誤的默認行為。

`window.onerror = function (message, url, line ) {`

 `console.log(message)`

 `return  false;`

`}`

圖像也支持error事件。只要圖像的src指定的URL返回的圖像格式不可被識別,就會觸發(fā)error事件。但是他的事件處理程序會接收event對象。

常見錯誤類型

  • 數(shù)據(jù)類型錯誤

  • 其實就是指我們在編寫代碼的過程前沒有確保使用的變量和函數(shù)參數(shù)的數(shù)據(jù)類型的正確性。因為JS是松散類型的,因此開發(fā)人員要編寫適當?shù)臄?shù)據(jù)類型檢測代碼。要注意的一點是,當進行類型判斷時,如果是基本類型,應該使用typeof來檢測,而對象的值則應該使用instanceof來進行檢測。

  • 類型轉換錯誤

  • 這種錯誤比較常見的是== , === 和 if , while , for這些控制語句中的布爾條件判斷。舉一個常見的例子:

`function  test(arr, arr2)  {`

 `if (!arr2) {`

 `return arr;`

`}`

`}`
  • 我們想的是,如果不存在arr2,就返回arr。如果arr2為undefined,滿足條件。如果arr2存在,且為0的話,仍然會以arr2不存在進行處理。顯然,這里就出現(xiàn)了邏輯上的錯誤。因此,要加上合適的判斷。
`if ( typeof arr2 === 'undefined' ) return arr`
  • 通信錯誤

  • 格式不正確的URL有關。

  • 服務器處理出現(xiàn)的錯誤。

錯誤上傳服務器

很多時候,我們都需要把錯誤信息上傳給服務器保存。那么,怎么上傳就是一個問題。

正如上面所說,Image對象也會觸發(fā)error事件,那么我們可以使用image的error事件。主要由以下幾個好處:

  • 支持度高。幾乎所有的瀏覽器都支持Image對象。

  • 可以避免跨域限制。

  • 記錄錯誤的過程中出問題的概率較低。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容