1. 程式人生 > 其它 >JavaScript()錯誤處理

JavaScript()錯誤處理

錯誤傳播

如果程式碼發生了錯誤,又沒有被try ... catch捕獲,那麼,程式執行流程會跳轉到哪呢?

function getLength(s) {
    return s.length;
}

function printLength() {
    console.log(getLength('abc')); // 3
    console.log(getLength(null)); // Error!
}

printLength();

如果在一個函式內部發生了錯誤,它自身沒有捕獲,錯誤就會被拋到外層呼叫函式,如果外層函式也沒有捕獲,該錯誤會一直沿著函式呼叫鏈向上丟擲,直到被JavaScript引擎捕獲,程式碼終止執行。

所以,我們不必在每一個函式內部捕獲錯誤,只需要在合適的地方來個統一捕獲,一網打盡:

'use strict';
function main(s) {
    console.log('BEGIN main()');
    try {
        foo(s);
    } catch (e) {
        console.log('出錯了:' + e);
    }
    console.log('END main()');
}

function foo(s) {
    console.log('BEGIN foo()');
    bar(s);
    console.log(
'END foo()'); } function bar(s) { console.log('BEGIN bar()'); console.log('length = ' + s.length); console.log('END bar()'); } main(null); /*執行結果: BEGIN main() BEGIN foo() BEGIN bar() 出錯了:TypeError: Cannot read property 'length' of null END main() */

bar()函式傳入引數null時,程式碼會報錯,錯誤會向上拋給呼叫方foo()

函式,foo()函式沒有try ... catch語句,所以錯誤繼續向上拋給呼叫方main()函式,main()函式有try ... catch語句,所以錯誤最終在main()函式被處理了。

至於在哪些地方捕獲錯誤比較合適,需要視情況而定。

非同步錯誤處理

編寫JavaScript程式碼時,我們要時刻牢記,JavaScript引擎是一個事件驅動的執行引擎,程式碼總是以單執行緒執行,而回調函式的執行需要等到下一個滿足條件的事件出現後,才會被執行。

例如,setTimeout()函式可以傳入回撥函式,並在指定若干毫秒後執行

function printTime() {
    console.log('It is time!');
}

setTimeout(printTime, 1000);
console.log('done');

上面的程式碼會先列印done,1秒後才會列印It is time!

如果printTime()函式內部發生了錯誤,我們試圖用try包裹setTimeout()是無效的:

'use strict';
function printTime() {
    throw new Error();
}

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

//執行結果
//done

原因就在於呼叫setTimeout()函式時,傳入的printTime函式並未立刻執行!緊接著,JavaScript引擎會繼續執行console.log('done');語句,而此時並沒有錯誤發生。直到1秒鐘後,執行printTime函式時才發生錯誤,但此時除了在printTime函式內部捕獲錯誤外,外層程式碼並無法捕獲。

所以,涉及到非同步程式碼,無法在呼叫時捕獲,原因就是在捕獲的當時,回撥函式並未執行。

類似的,當我們處理一個事件時,在繫結事件的程式碼處,無法捕獲事件處理函式的錯誤。

例如,針對以下的表單:

<form>
    <input id="x"> + <input id="y">
    <button id="calc" type="button">計算</button>
</form>
宣告 歡迎轉載,但請保留文章原始出處:) 部落格園:https://www.cnblogs.com/chenxiaomeng/ 如出現轉載未宣告 將追究法律責任~謝謝合作