閱讀231 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go 掃碼領紅包係統功能開發
  下一篇:go 分布式事務雲市場分析