1. 程式人生 > >錯誤處理(一)

錯誤處理(一)

nbsp 事件處理程序 tor 如何 eof 不能 exp IT 要求


try-catch語句

try{
    //可能會導致錯誤的代碼
}catch(error){
    //在錯誤發生時怎麽處理
}

如果try塊中的任何代碼發生了錯誤,就會立即退出代碼執行過程,然後接著執行catch塊。此時,catch塊會接收到一個包含錯誤信息到對象。與其他語言中不同到是,
即使你不想使用這個錯誤對象,也要給他起個名字。

try{
    window.someNonexistentFunction();
}catch(error){
    console.log(error.message);
}

finally

function
testFinally(){ try{ return 2; }catch(error){ return 1; }finally{ return 0; } }

只要代碼中包含finally子句,那麽無論try還是catch語句塊中的return語句都將被忽略。因此,在使用finally子句之前,一定要非常清楚你想讓代碼怎麽樣。


錯誤類型
ECMA-262定義了7種錯誤類型: Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError

1)、Error
Error是基類型,其他錯誤類型都繼承自該類型,Error類型都錯誤很少見,如果有也是瀏覽器拋出的;這個基類型的主要目的是提供開發人員拋出自定義錯誤
2)、EvalError

new eval(); //TypeError: eval is not a constructor

EvalError不再會被JavaScript拋出,但是EvalError對象仍然保持兼容性.有鑒於此,加上實際開發中很少使用eval(),所以遇到這種錯誤類型的可能性極小。
3)、RangeError

var items1 = new Array(-20); // RangeError: Invalid array length
var items2 = new Array(Number.MAX_VALUE); //RangeError: Invalid array length

RangeError類型的錯誤會在數值超出相應範圍觸發。例如,在定義數組是,指定了數組不支持的項數
4)、ReferenceError

var obj = x; //ReferenceError: x is not defined
eval = foo; // ReferenceError: foo is not defined

在找不到對象的情況下,會發生ReferenceError,通常,在訪問不存在的變量時,就會發生這種錯誤
5)、SyntaxError

eval(‘a ++ b‘); //SyntaxError: Unexpected identifier

當我們把語法錯誤的js字符傳入eval()函數時,就會導致此類錯誤。如果語法錯誤的代碼出現在eval()函數之外,則不太可能使用SyntaxError。
6)、TypeError

var o = new 10; //TypeError: 10 is not a constructor
console.log(‘name‘ is true); //TypeError: Cannot use ‘in‘ operator to search for ‘name‘ in true
Function.prototype.toString.call(‘name‘); //TypeError: Function.prototype.toString requires that ‘this‘ be a Function

TypeError類型在js中會經常用到,在變量中保存著意外的類型,或者訪問不存在的方法時,都會導致這種錯誤,錯誤的原因多種多樣,但歸根結底還是由於在執行
特定類型的操作時,變量的類型並不符合要求所致。
7)、URIError
在使用encodeURI()或decodeURI(),而URI格式不正確時,就是導致URIError錯誤。這種錯誤也很少見,因為前面說的這個兩個函數的容錯性非常高。

8)、要想知道錯誤的類型,可以像下面這樣處理

try{
    someFunction()
}catch(error){
    if(error instanceof TypeError){
        console.log(‘處理類型錯誤‘);
    }else if(error instanceof ReferenceError){
        console.log(‘處理引用錯誤‘);
    }else{
        console.log(‘處理其他類型的錯誤‘);
    }
}

9)、合理使用try-catch
使用try-catch最適合處理那些我們無法控制的錯誤。假設你在使用大型js庫中的函數,該函數可能會有意無意地拋出一些錯誤。由於我們不能修改這個庫的源代碼,所以大可
將該函數的調用放在try-catch語句當中,萬一有什麽錯誤時,也好恰當地處理
在明明白白地知道自己地代碼會發生錯誤,再使用try-catch語句就不太合適了。例如,如果傳遞給函數地參數時字符串而非樹枝,就會造成函數出錯,那麽就應該檢查參數地類型,
然後再決定如何去做。


拋出錯誤
在遇到throw操作符時,代碼會立即停止執行。僅當有try-catch語句捕獲被拋出的值時,代碼才會繼續執行

function process(values){
    values.sort();
    for(var i=0; i<values.length; i<len; i++){
        if(values[i] > 100){
            return values[i];
        }
    }
    return -1;
}

如果執行這個函數時傳給它一個字符串參數,那麽對sort()對調用就會失敗。對此,不同對瀏覽器會給出不同對錯誤消息,但都不是特別明確。這個情況下,帶有適當的
自定義錯誤能夠顯著提升代碼的可維護性。

function process(values){
    if(!(values instanceof Array)){
        throw new Error("process(): Argument must be an array");
    }
    values.sort();
    for(var i=0; i<values.length; i<len; i++){
        if(values[i] > 100){
            return values[i];
        }
    }
    return -1;
} 

建議讀者在開發javascript代碼的過程中,重點關註函數和可能導致函數執行失敗的因素。良好的錯誤處理機制應該可以確保代碼中只發生你自己拋出的錯誤。

error事件
任何沒有通過try-catch處理的錯誤都會觸發window對象的error事件。這個事件時web瀏覽器最早支持的事件之一。

window.onerror = function(message, url, line){
    console.log(message);
}

只要發生錯誤,無論是不是瀏覽器生成的,都會觸發error事件,並執行這個事件處理程序。

錯誤處理(一)