目錄
1. 文法
2. 詳解
3. 無條件的catch塊
4. finally塊
5. 嵌套try
1. 文法
try { try_statements } [catch (exception_var_1 if condition_1) { // non-standard catch_statements_1 }] ... [catch (exception_var_2) { catch_statements_2 }] [finally { finally_statements }]
try_statements
需要被執行的語句。
catch_statements_1
,
catch_statements_2
如果在
try
塊裡有異常被抛出時執行的語句。
exception_var_1
,
exception_var_2
用于儲存關聯
catch
子句的異常對象的辨別符。
condition_1
一個條件表達式。
finally_statements
在
try
語句塊之後執行的語句塊。無論是否有異常抛出或捕獲這些語句都将執行。
2. 詳解
try
語句包含了由一個或者多個語句組成的
try
塊, 和至少一個
catch
塊或者一個
finally
塊的其中一個,或者兩個兼有, 下面是三種形式的
try
聲明:
-
try...catch
-
try...finally
-
try...catch...finally
catch
子句包含
try
塊中抛出異常時要執行的語句。也就是,你想讓
try
語句中的内容成功, 如果沒成功,你想控制接下來發生的事情,這時你可以在
catch
語句中實作。 如果在
try
塊中有任何一個語句(或者從
try
塊中調用的函數)抛出異常,控制立即轉向
catch
子句。如果在
try
塊中沒有異常抛出,會跳過
catch
子句。
finally
子句在
try
塊和
catch
塊之後執行但是在下一個
try
聲明之前執行。無論是否有異常抛出或捕獲它總是執行。
你可以嵌套一個或者更多的
try
語句。如果内部的
try
語句沒有
catch
子句,那麼将會進入包裹它的
try
語句的
catch
子句。
3. 無條件的 catch
塊
catch
所謂無條件catch塊就是單個子句的try..catch 抛出的異常都會被catch捕獲,例如,當在下面的代碼中發生異常時,控制轉移到
catch
子句。
try {
nonExistentFunction(); // 不存在的函數
} catch (error) {
console.error(error);
// 控制台列印: ReferenceError: nonExistentFunction is not defined
// 被catch捕獲錯誤。
}
列印出來的錯誤時可以自定義的。
catch
塊指定一個辨別符,該辨別符儲存由
throw
語句指定的值。
catch
塊是唯一的,因為當輸入
catch
塊時,JavaScript 會建立此辨別符,并将其添加到目前作用域;辨別符僅在
catch
塊執行時存在;
catch
塊執行完成後,辨別符不再可用。
try {
throw "自定義一些文字錯誤"; // generates an exception
}
catch (e) {
console.log(e); // 控制台列印:自定義一些文字錯誤
}
try {
throw {name: '張三'}; // 自定義
}
catch (e) {
console.log(e); // 列印: {name: '張三'}
}
try
塊中的抛出一個異常時,
exception_var
(如
catch (e)
中的
e
)用來儲存被抛出聲明指定的值。你可以用這個辨別符來擷取關于被抛出異常的資訊。
這個辨別符是
catch
子語句内部的。換言之,當進入
catch
子語句時辨別符建立,
catch
子語句執行完畢後,這個辨別符将不再可用。
4. finally
塊
finally
finally
塊包含的語句在
try
塊和
catch
之後,
try..catch..finally
塊後的語句之前執行。請注意,無論是否抛出異常
finally
子句都會執行。此外,如果抛出異常,即使沒有
catch
子句處理異常,
finally
子句中的語句也會執行。
openMyFile()
try {
// tie up a resource
writeMyFile(theData);
}
finally {
closeMyFile(); // always close the resource
}
5. 嵌套try
例子1:
try {
try {
throw new Error("oops"); // 抛出oops錯誤對象
}
finally {
console.log("finally"); // 必須執行的
}
}
catch (ex) {
console.error("outer", ex.message);
}
// 結果:
// "finally"
// "outer" "oops"
例2 如果我們已經在 try 語句中,通過增加一個 catch 語句塊捕獲了異常
try {
try {
throw new Error("oops"); // 抛出異常
}
catch (ex) {
console.error("inner", ex.message); // 被捕獲到了
}
finally {
console.log("finally"); // 怎麼樣都會執行
}
}
catch (ex) {
console.error("outer", ex.message); // 屬于這個try catch 沒有異常抛出
}
// 結果:
// "inner" "oops"
// "finally"
例3 在新增的catch裡不幹正事繼續抛錯誤
try {
try {
throw new Error("oops"); // 異常
}
catch (ex) {
console.error("inner", ex.message); // 捕獲到異常
throw ex; // 不幹正事的抛出異常 但是還是會先執行finally内的内容
}
finally {
console.log("finally"); // try 和 catch 執行完就執行。不管别人
}
}
catch (ex) {
console.error("outer", ex.message); // 捕獲到屬于這個try -catch 的異常
}
// 結果:
// "inner" "oops"
// "finally"
// "outer" "oops"
例4 特别!!!
function setName () {
try {
try {
throw new Error("oops");
}
catch (ex) {
console.error("inner", ex.message);
throw ex;
}
finally {
console.log("finally");
return;
}
}
catch (ex) {
console.error("outer", ex.message);
}
// 注: 此 try catch 語句需要在 function 中運作才能作為函數的傳回值, 否則直接運作會報文法錯誤
// 結果:
// "inner" "oops"
// "finally"
}
如果從塊中傳回一個值,那麼這個值将會成為整個
finally
的傳回值,無論是否有
try-catch-finally
語句在
return
和
try
中。這包括在
catch
塊裡抛出的異常。因為 finally 塊裡的 return 語句,"oops" 沒有抛出到外層,從 catch 塊傳回的值同樣适用。
catch