javascript異常
所謂異常就是程序的非正常運行酣藻,通俗的說就是程序發(fā)生了錯誤状勤。至于這些錯誤,有的是認為疏忽造成的異常(Exception)迂求,有的是程序本身的錯誤(Error)默伍。
比如有的時候我們希望兩個數(shù)相加欢嘿,因為人為疏忽,代碼里寫成了乘號也糊,那么這種錯誤大部分情況下是得不到你想要的結(jié)果的炼蹦,但是幸運又不幸的是,這個程序沒有語法錯誤狸剃,依然可以返回結(jié)果掐隐,但是無法報錯。
另一種情況就是你的程序無法被JavaScript引擎執(zhí)行钞馁,這種異常引擎會拋出一個異常虑省,這個時候如果你沒有捕獲異常,那么程序就會被中斷僧凰,無法執(zhí)行下去探颈。
code1:
alert('js運行了!')
let a = b + 1
alert('程序結(jié)束')
這個時候我們的瀏覽器客戶端作為JavaScript引擎就會捕獲一條異常報告训措,俗稱報錯了伪节。
因為此時代碼中的 b 是尚未定義的光羞,拋出了ReferenceError這個異常,下面是JavaScript中經(jīng)常遇到的異常類型架馋,大概分類有如下幾種:
- EvalError: raised when an error occurs executing code in eval()
- RangeError: raised when a numeric variable or parameter is outside of its valid range
- ReferenceError: raised when de-referencing an invalid reference
- SyntaxError: raised when a syntax error occurs while parsing code in eval()
- TypeError: raised when a variable or parameter is not a valid type
- URIError: raised when encodeURI() or decodeURI() are passed invalid parameters
上面的六種異常對象都繼承自Error對象狞山。他們都支持以下兩種構(gòu)造方法: new Error();
new Error(“異常信息”);
try/catch/finlly語句
上面介紹了幾種程序拋出的異常全闷,那么現(xiàn)在就需要對異常進行處理叉寂,其中try從句中定義了需要處理和判斷的代碼塊,catch從句中放置當程序發(fā)生異常后進行處理的代碼总珠,catch從句后跟隨finally塊屏鳍,finally中放置清理代碼,不管try塊中是否產(chǎn)生異常局服。finally塊中的邏輯代碼都會執(zhí)行钓瞭,其中catch和finally都是可選的,但是必須選擇兩種中之一和try從句組成完整的語句淫奔。
try山涡、catch、finally語句塊都需要使用花括號括起來唆迁,即使語句中只有一條語句也不能省略鸭丛,記住,這里的花括號是必須的
下面的代碼說明了try/catch/finlly語句的用法和作用
try {
// 這里是你可能會出現(xiàn)異常的代碼
// 可以通過throw直接拋出異常
// 或者通過調(diào)用一個方法間接拋出
} catch(e) {
// 當try語句塊拋出了異常唐责,這里的代碼就會執(zhí)行
// 可以通過局部變量e來獲取該異常Error對象的信息
// 可以通過throw重新拋出異常
} finally {
// 無論是否拋出異常鳞溉,都會執(zhí)行這里的代碼
// 終止語句塊的方法有:
// 1. 正常執(zhí)行最后一條語句終止
// 2. 通過break、continue鼠哥、或return終止
// 3. 拋出異常熟菲,被try捕獲
// 4. 拋出異常,異常未被捕獲朴恳,繼續(xù)向上傳播
}
我們看到抄罕,catch后面接了個標識符e,這個標識符和函數(shù)參數(shù)很想于颖,當捕獲一個異常時呆贿,把和這個異常相關(guān)的值(比如Error對象)賦值給這個參數(shù),和普通的變量不同恍飘,這條catch句中的標識符具有塊級作用域榨崩,它只在catch語塊內(nèi)有定義。這個Error對象有幾個主要屬性章母,如下:
- description: 錯誤描述 (僅IE可用).
- fileName: 出錯的文件名 (僅Mozilla可用).
- lineNumber: 出錯的行數(shù) (僅Mozilla可用).
- message: 錯誤信息 (在IE下同description)
- name: 錯誤類型.
- number: 錯誤代碼 (僅IE可用).
- stack: 像Java中的Stack Trace一樣的錯誤堆棧信息 (僅Mozilla可用).
下面就使用一個try/catch語句把pic1中的代碼包裹起來
try{
//這里放置可能會出錯的代碼
let a = b + 1
} catch(e)
{
//代碼出錯后執(zhí)行這里母蛛。
console.debug(' name: ' + e.name +
' message: ' + e.message +
' lineNumber: ' + e.lineNumber +
' fileName: ' + e.fileName +
' stack: ' + e.stack);
} finally {
console.log('執(zhí)行了finally')
}
將上面的代碼復制到chrome控制臺,會看到下面的信息乳怎,說明異常已經(jīng)被捕獲彩郊,并且前弯,最終執(zhí)行了finally
通常狀況下,解釋器執(zhí)行到try語句塊的尾部秫逝,然后開始執(zhí)行finally中的代碼恕出,以便進行必要的清理工作。當由于return违帆、continue浙巫、break語句使得解釋器跳出try語句塊時,解釋器在執(zhí)行新的目標代碼之前先執(zhí)行finally中的代碼刷后。
如果在try中產(chǎn)生了異常的畴,而且存在一條與之相關(guān)的catch從句來處理這個異常,解釋器首先執(zhí)行catch中的邏輯尝胆,然后執(zhí)行finally中的邏輯丧裁,如果不存在處理異常的局部catch從句,解釋器會首先執(zhí)行finally中的邏輯含衔,然后向上傳播異常煎娇,直到找到能處理這個異常的catch從句。
如果finally快使用了return贪染、continue缓呛、break或者throw語句時程序發(fā)生跳轉(zhuǎn),或者通過調(diào)用了拋出異常的方法改變了程序執(zhí)行流程抑进,不管這個跳轉(zhuǎn)使程序掛起還是繼續(xù)執(zhí)行强经,解釋器都會將其忽略。例如finally從句拋出一個異常寺渗,這個異常將替代正在拋出的異常匿情。如果finally從句運行倒了return語句,盡管已經(jīng)拋出了異常且這個異常還沒有處理信殊,這個方法依然會正常返回炬称。
throw語句
在JavaScript運行的時候,若使用throw語句時就會電視的拋出異常涡拘。
throw語句的語法如下:
throw expression
expression的值是任意類型的玲躯。可以拋出代表錯誤碼的數(shù)字亦或是讓人明白意思的字符串鳄乏。JavaScript解釋器拋出異常的時候通常采用Error類型和其子類型跷车。
function getMoney(money) {
// 若傳入的參數(shù)非法,直接拋出異常
if (money < 0)
throw new Error('金額不能為負數(shù)')
return money
}
在chrome控制臺里試試橱野,這個時候如果傳入的參數(shù)小于0就會直接拋出一個自定義字符串的異常了朽缴,見下圖:
最后
當程序拋出異常時,JavaScript解釋器會立即停止當前正在執(zhí)行的邏輯水援,并跳轉(zhuǎn)至就近的異常處理程序密强,如果拋出異常的代碼塊中沒有try/catch語句茅郎,解釋器會檢查更高層次的閉合代碼塊,看它是否有關(guān)聯(lián)異常處理程序或渤。以此類推系冗,直到找到異常處理程序為止