JS中的錯誤處理與調試


錯誤處理

try-catch語句

在使用try-catch時,我們通常是把可能會出錯的代碼放在try語句塊中,把錯誤處理程序放在catch語句塊中。

try {
    
}
catch(err){

}

那麼,當我們執行try語句塊中的代碼遇到錯誤時,會跳出try語句塊,然後執行catch中的代碼。通過上面的代碼可以發現,catch會接收一個錯誤相關的對象err,err中存有與錯誤有關的信息,可能不同瀏覽器中err實際包含的內容有着不同,但是所有的瀏覽器均支持一個錯誤信息的message屬性。可以通過err.message獲取到。

finally子句

如果在try-catch後面添加了一個finally子句,那麼不管try中的代碼執行會不會出錯,都會執行finally中的代碼。也就是說,不管執行了try,還是catch,不管try或catch中的語句是什麼——甚至包括return語句,都會執行finally中的代碼,那麼就是說,如果存在finally,那麼try或catch中的return會失效。

try {
    return 1;
}
catch(err)
{
    return -1;
}
finally {
    return 0;
}

通過上面的講解我們可以知道,結果爲:0

錯誤類型

代碼執行過程中會出現的錯誤主要有以下幾種:

  • Error 基類型,其他類型的錯誤均繼承自該類型。
  • RangeError 數值超出相應的範圍,如new Array(-20)
  • EvalError 使用eval()函數出錯時拋出,即沒有吧eval()函數當成函數直接調用
  • ReferenceError 引用錯誤

var obj = x ; //ReferenceError: x is not defined.

  • SyntaxError 語法錯誤
  • TypeError 類型錯誤,執行於特定操作時,變量類型不符合要求。
  • URIError URI格式不正確

throw拋出錯誤

通過throw可以隨時拋出自定義錯誤。

  1. 拋出錯誤的時機
    在出現某種特定的已知錯誤條件,導致函數無法正常執行時拋出錯誤。常見情況爲,函數參數的傳遞。比如我們希望函數接收一個數組參數,在函數內部有直接調用數組方法。那麼如果傳進來一個數字,就會出錯。因此可以加入一個判斷語句,如果傳入的參數不爲數組,則手動拋出一個錯誤。
  2. try-catch與throw
    try-catch最適合處理那些我們無法控制的錯誤。比如:當你使用別人的代碼時,可能無法修改源碼,那麼這種情況下,就可以把代碼運行在try語句塊中。throw則是更多可以用在已知錯誤條件的情況。
    另外,需要注意的是,當使用try-catch時,我們是希望自己對錯誤進行處理,而不是使用瀏覽器默認的錯誤處理。throw拋出錯誤的目的則是提供錯誤發生的具體原因的消息。(比如,我們可以在throw拋出的錯誤中添加出錯的函數及錯誤原因,這樣,當代碼量比較多時,可以快速定位錯誤的位置。)

error事件

所有不通過try-catch處理的錯誤都會觸發window的error事件。要制定window的error事件,必須使用DOM0級的onerror,他沒有遵循DOM2級事件的標準格式。

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

}

通過代碼可以看到,onerror事件的回調函數有三個參數:錯誤信息,錯誤的URL,錯誤所在的行號
圖像也支持error事件,當src指定的URL不能返回可識別的圖像格式,就會觸發事件。事件的處理函數中包含一個對象:event。它的目標爲圖像。即,event.target爲這個圖像節點。

常見的錯誤類型(瞭解錯誤類型以在編寫程序時儘量避免錯誤)

  • 數據類型錯誤 :比如,對一個非數組調用了數組方法。
  • 類型轉換錯誤:比如,== , != , if, for, while中的條件判斷(布爾值)
  • 通信錯誤: 比如,AJAX發送的數據錯誤,服務器響應的數據錯誤

錯誤調試技術

作爲小白的我,以前最喜歡使用的錯誤調試技術莫過於alert(),這樣查看錯誤的方式實在是效率太低。以下爲幾種高效的:

  • 瀏覽器中有控制檯,我們可以在控制檯打印相關的信息查找錯誤。
    1. console.log(message)打印一般性信息
    2. console.info(message)打印信息性消息
    3. console.warn(message)打印警告信息
    4. console.error(message)打印錯誤信息
  • 將消息記錄打印到當前頁面的某一具體位置

在頁面中開闢一塊區域,專門用來打印錯誤信息。這個區域可以是一個元素,總是可以出現在頁面中,但僅用於調試目的。

異步任務的錯誤處

使用try-catch來處理錯誤程序時,要注意:哪裏出錯在哪裏try-catch.

function printTime() {
    throw new Error("66666");
}

try {
    setTimeout(printTime, 1000);
    console.log('done');
} catch (e) {
    console.log('error');
}

原理:setTimeout爲異步的任務,因此會直接執行打印done的語句,此時沒有報錯,不會執行catch中的代碼。然後到了執行異步任務,瀏覽器接收到錯誤。

這裏的結果是:打印done,瀏覽器的error事件被觸發,因此不會打印error

function printTime() {
    try {
    throw new Error("66666");
    } catch (e) {
    console.log('error');
}
}
setTimeout(printTime, 1000);
    console.log('done');

這樣就可以用我們自己的catch來處理錯誤了。
記住一點:對會拋出錯誤的代碼寫在try語句塊中,try-catch和throw要在同一層級。

錯誤上傳

  • AJAX
  • Image對象

建議使用Image對象,主要原因:

  • 所有瀏覽器都支持Image對象,包括不支持XMLHttpRequest對象的瀏覽器。
  • 可以避免跨域限制。這種情況下使用XMLHttpRequest是不行的。
  • 在記錄錯誤的過程中出問題的概率比較低。大多數AJAX通信都是通過Javascript庫提供的包裝函數來處理的,如果庫的代碼本身就有問題,那麼錯誤消息是不會被記錄的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章