目录
1. 语法
2. 详解
3. 无条件的catch块
4. finally块
5. 嵌套try
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
语句块之后执行的语句块。无论是否有异常抛出或捕获这些语句都将执行。
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
子句。
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
子语句执行完毕后,这个标识符将不再可用。
finally
块finally
块包含的语句在try
块和catch
之后,try..catch..finally
块后的语句之前执行。请注意,无论是否抛出异常finally
子句都会执行。此外,如果抛出异常,即使没有catch
子句处理异常,finally
子句中的语句也会执行。
openMyFile()
try {
// tie up a resource
writeMyFile(theData);
}
finally {
closeMyFile(); // always close the resource
}
例子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
中。这包括在catch
块里抛出的异常。因为 finally 块里的 return 语句,"oops" 没有抛出到外层,从 catch 块返回的值同样适用。