錯誤處理(一)
try-catch語句
try{ //可能會導致錯誤的代碼 }catch(error){ //在錯誤發生時怎麽處理 }
如果try塊中的任何代碼發生了錯誤,就會立即退出代碼執行過程,然後接著執行catch塊。此時,catch塊會接收到一個包含錯誤信息到對象。與其他語言中不同到是,
即使你不想使用這個錯誤對象,也要給他起個名字。
try{ window.someNonexistentFunction(); }catch(error){ console.log(error.message); }
finally
functiontestFinally(){ 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
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 lengthvar 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事件,並執行這個事件處理程序。
錯誤處理(一)