JavaScript錯誤處理
我們在編寫js過程中,難免會遇到一些代碼錯誤問題需要找出來;有時怕因為js問題導致用戶體驗差,這裏給出一些常見錯誤及解決方法
錯誤分類
語法錯誤
也稱為解析錯誤,發生在傳統編程語言編譯時,在JavaScript中發生在解釋時,這些錯誤是由代碼中的意外字符直接引起的,然後就不能直接編譯/解釋
eg:在一行代碼因缺少右括號,產生了語法錯誤
發生語法錯誤時,就不能繼續執行代碼;在JavaScript中,隻有在同一個線程中的代碼會受語法錯誤的影響;在其他線程中的代碼和其他外部引用的文件中的代碼,如果不依賴於包含錯誤的代碼,則可以繼續執行
運行時錯誤
也稱為異常(exception,在編譯期/解釋器後);此時,問題並不出在代碼的語法上,而是嚐試完成的一個操作,在某些情況下是非法的
eg:window.openMyFile();
因不存在openMyFile()方法,瀏覽器會返回一個異常;異常隻影響發生的線程,其他JavaScript線程即可繼續正常的執行
另外ECMA-262定義了7種錯誤類型:
1.Error 錯誤
2.EvalError 全局錯誤
3.RangeError 引用錯誤
4.ReferenceError 參數錯誤
5.SyntaxError 語法錯誤
6.TypeError 類型錯誤
7.URIError 編碼錯誤
其中Error是基類型,其他類型繼承自它。Error類型很少見,一般由瀏覽器拋出。EvalError類型表示全局函數eval()的使用方式與定義不同時拋出,但實際上並不能產生這個錯誤,所以實際上碰到的可能性不大。在使用encodeURI()和decodeURI()時,如果URI格式不正確時,會導致URIError錯誤。但因為URI的兼容性非常強,導致這種錯誤幾乎見不到
處理錯誤
瀏覽器自身具有報錯的功能。以IE為例,出錯時會彈出錯誤調試框。但這需要開啟腳本調試,設置方法為:工具->Internet Options選項->高級->禁用腳本調試,取消勾選即可。其它瀏覽器大同小異
onerror事件處理函數
它是第一個用來協助JavaScript處理錯誤的機製;頁麵上出現異常時,error事件便在window對象上觸發
<script type="text/javascript">
window.onerror = function() {
alert("發生錯誤!");
}
</script>
<body ></body>
在上述代碼中,在頁麵載入時嚐試調用不存在的函數,此時會引發一個異常,彈出“發生錯誤”的錯誤信息;但瀏覽器的錯誤信息也顯示出來了,如何在瀏覽器上隱藏它呢,隻需onerror方法返回一個true即可
window.onerror = function() {
alert(“發生錯誤!”);
return true;
}
取出錯誤信息
onerror處理函數提供了三種信息來確定錯誤確切的性質:
1.錯誤信息——對於給定錯誤,瀏覽器會顯示同樣的信息;
2.URL——在哪個文件中發生了錯誤;行號——給定URL中發生錯誤的行號
window.onerror = function(sMessage, sUrl, sLine) {
alert("發生錯誤!\n" + sMessage + "\nURL:" + sUrl + "\nLine Number:" + sLine);
return true;
}
圖像載入錯誤
window對象並非唯一支持onerror事件處理函數的對象,它對圖像對象也提供支持;當一個圖像由於文件不存在等原因未能成功載入時,error事件便在這個圖像上觸發
<img src=”amigo.jpg” onerror=”alert(‘載入圖片時發生錯誤')”/>
上例直接在HTML中分配onerror事件處理函數。當然也可以通過腳本來分配事件處理函數,在設置圖像的src特性前,必須等待頁麵完全載入
<script type="text/javascript">
function handleLoad() {
document.images[0].onerror = function() {
alert("載入圖片時發生錯誤!");
};
document.images[0].src = "amigo.jpg";
}
</script>
<img/>
注意:與window對象的onerror事件處理函數不同,image的onerror事件可接收任何的額外信息的參數
處理語法錯誤
onerror還能處理語法錯誤。但有一點必須注意,事件處理函數必須是頁麵中第一個出現的代碼,因為如果語法錯誤出現在設置事件處理函數之前出現,事件處理函數就沒有用了
注意:語法錯誤會完全停止代碼的執行
說明:使用onerror事件處理函數的主要的問題是,它是BOM的一部分,所以,沒有任何標準能控製它的行為。因此,不同的瀏覽器使用這個事件處理錯誤的方式有明顯的不同
eg:在IE中發生error事件時,正常的代碼會繼續執行,所有的變量和數據都保留下來,並可通過onerror事件處理函數訪問。在Mozilla中,正常的代碼執行都會結束,同時所有的錯誤發生之前的變量和數據都被銷毀
try…catch語句
try 語句測試代碼塊的錯誤
catch 語句處理錯誤
throw 語句創建自定義錯誤
ECMPScript第三版,引入了try…catch語句
try { //嚐試著執行 try 包含的代碼
window.abcdefg(); //不存在的方法
} catch (e) { //如果有錯誤,執行 catch,e 是異常對象
alert('發生錯誤啦,錯誤信息為:' + e); //直接打印調用 toString()方法
}
ECMAScript標準在try…catch語句中隻能有一個catch語句,因為JavaScript是弱類型的語言,沒辦法指明catch子句中異常的特定類型。不管錯誤是什麼類型,都由同一個catch語句處理。一般不建議使用try-catch,因為它比一般語句消耗資源更多,負擔更大。所以在萬不得已,無法修改代碼,不能通過普通判斷的情況下才去使用try-catch
finally子句
try {
window.abcdefg();
} catch (e) {
alert('發生錯誤啦,錯誤信息為:' + e.stack);
} finally { //總是會被執行
alert('我都會執行!');
}
finally用於包含無論是否有異常發生都要執行的代碼,這對關閉打開的鏈接和釋放資源很有用,一般是為了防止出現異常後,無法往下再執行的備用
嵌套try…catch語句
用來處理catch子句中的錯誤問題
try {
eval("a ++ b");
} catch(oException) {
alert("發生錯誤!");
try {
var aError = new Array(1000000000000000000000000000000000000000);
} catch(exception) {
alert("在catch子句中發生錯誤!");
}
} finally{
alert("已完成")
}
拋出異常的throw語句
使用catch來處理錯誤信息,如果處理不了,我們就把它拋出丟掉;把 throw 與 try 和 catch 一起使用,那麼您能夠控製程序流,並生成自定義的錯誤消息
在ECMAScript第三版引入,用於有目的的拋出異常,拋出的錯誤對象可為字符串、數字、布爾值或實際的對象,也可以拋出Error對象(其構造函數隻有一個,即錯誤信息)。eg1: throw new Error(“錯誤產生!”);
function addTwoNumber(a, b) {
if (arguments.length < 2) {
throw new Error("需要傳入兩個數字!");
}
}
try {
result = addTwoNumber(90);
} catch(oException) {
if (oException instanceof SyntaxError) {
alert("SyntaxError:" + oException.message);
} else if (oException instanceof Error){
alert(oException.message);
}
}
Error對象
發生錯誤時,JavaScript有個Error基類用於拋出。它有兩個特性:
1.name——表示錯誤類型的字符串
2.message——實際的錯誤信息
Error對象的name對應於它的類,可以是如下值之一:
EvalError:錯誤發生在eval()函數中;
RangeError:數字值超出JavaScript可表示的範圍;
ReferenceError:使用了非法的引用;
SyntaxError:在eval()函數調用中發生了語法錯誤,其他的愈發錯誤由瀏覽器報告,無法通過try…catch處理
TypeError:變量的類型不是預期所需的;
URIError:在encodeURI或decodeURI函數發生了錯誤
判斷錯誤類型
可采取如下兩種方法來判斷錯誤類型,第一種根據異常的name屬性判斷
try {
eval("a ++ b");
} catch(oException) {
if (oException.name = "SyntaxError") {
alert("發生SyntaxError!");
} else {
alert("發生其他錯誤!");
}
}
第二種采用instanceof操作符
try {
eval("a ++ b");
} catch(oException) {
if (oException instanceof SyntaxError) {
alert("發生SyntaxError!");
} else {
alert("發生其他錯誤!");
}
}
調試錯誤:
在JavaScript初期,瀏覽器並沒有針對JavaScript提供調試工具,所以開發人員就想出了一套自己的調試方法,比如alert()。但使用alert()來調試錯誤比較麻煩,需要重複剪切和粘貼,如果遺忘掉沒有刪掉用於調試的alert()將特別頭疼,現在我們有更好的調試方法
將消息記錄到控製台
console.error('錯誤!'); //紅色帶叉
console.info('信息!'); //白色帶信息號
console.log('日誌!'); //白色
console.warn('警告!'); //黃色帶感歎號
var num1 = 1;
console.log(typeof num1); //得到 num1 的類型
var num2 = 'b';
console.log(typeof num2); //得到 num2 的類型
var result = num1 + num2;
alert(result); //結果是 1b,匪夷所思
與alert()比較:因為alert()會阻斷後麵代碼的執行,看過之後還要刪,刪完估計一會兒又忘了。如果用了congsole.log的話,所有要調試的變量一目了然,也不需要刪除,放著也沒事
調試工具
瀏覽器都自帶了自己的調試工具,而開發人員隻習慣了Firefox一種,所以很多情況下,在Firefox開發調試,然後去其他瀏覽器做兼容。其實Firebug工具提供了一種Web版的調試工具:Firebug lite
調試步驟
1、設置斷點
2、單步調試:五個按鈕
重新運行:重新單步調試
斷繼:正常執行代碼
單步進入:一步一步執行流程
單步跳過:跳到下一個函數塊
單步退出:跳出執行到內部的函數
3、監控
4、控製台
最後更新:2017-05-03 12:00:37