(十三)异常处理
1. try/catch/finally
try/catch/finally
是 JavaScript 异常处理语句。
try {
//调试代码块
} catch(e) {
//捕获异常,并进行异常处理的代码块
} finally{
//后期清理代码块
}
在正常情况下,JavaScript 按顺序执行 try
子句中的代码,如果没有异常发生,将会忽略 catch
子句,跳转到 finally
子句中继续执行。
如果在 try
子句运行时发生错误,或者使用 throw 语句主动抛出异常,则执行 catch
子句中的代码,同时传入一个参数,引用 Error
对象。
不管 try
语句是否完全执行,finally
语句最后都必须要执行,即使使用了跳转语句跳出了异常处理结构,也必须在跳出之前先执行 finally
子句。
2. Error
通过 Error
的构造器可以创建一个错误对象。当运行时错误产生时,Error
的实例对象会被抛出。Error
对象也可用于用户自定义的异常的基础对象。
创建自定义异常的语法:
new Error([message])
参数说明:
message
:可选。可阅读的错误描述信息。
ECMA-262 规范了 7 种错误类型,具体说明如下。其中 Error
是基类,其他 6 种错误类型是子类,都继承 Error
基类。Error
类型的主要用途是自定义异常对象。
下面列出了各种内建的标准错误类型。
Error
:普通异常。与throw
语句和try/catch
语句一起使用,属性name
可以读写异常类型,message
属性可以读写详细错误信息。EvalError
:不正确的使用eval()
方法时抛出。SyntaxError
:出现语法错误时抛出。RangeError
:数字超出合法范围时抛出、ReferenceError
:读取不存在的变量时抛出,无效引用。TypeError
:变量或参数不属于有效类型。URIError
:URI 编码和解码错误时抛出。例如,给encodeURI()
或decodeURI()
传递的参数无效。
3. throw
throw
语句用来抛出一个用户自定义的异常。当前函数的执行将被停止(throw
之后的语句将不会执行),并且控制将被传递到调用堆栈中的第一个 catch
块。如果调用者函数中没有 catch
块,程序将会终止。
try {
console.log('before throw');
throw new TypeError('This is a TypeError');
console.log('after throw'); // 这条语句不会执行
} catch (e) {
console.log(e.name);
console.log(e.message);
}
/*
before throw
TypeError
This is a TypeError
*/
4. 关于嵌套的 try 块
任何给定的异常只会被离它最近的封闭 catch
块捕获一次。当然,在 “inner” 块抛出的任何新异常 (因为 catch
块里的代码也可以抛出异常),将会被 “outer” 块所捕获。
try {
try {
throw new Error('oops')
} catch (e) {
console.log('[inner] ' + e.message);
throw e;
} finally {
console.log('[inner] finally');
}
} catch (e) {
console.log("[outer] " + e.message);
}
/*
[inner] oops
[inner] finally
[outer] oops
*/
如果从 finally
块中返回一个值,那么这个值将会成为整个 try-catch-finally
的返回值,无论是否有 return
语句在 try
和 catch
中。这包括在 catch
块里抛出的异常。
try {
try {
throw new Error('oops')
} catch (e) {
console.log('[inner] ' + e.message);
throw e; // 这里抛出的异常被 return 语句给覆盖了,所以外层无法捕获
} finally {
console.log('[inner] finally');
return;
}
} catch (e) {
console.log("[outer] " + e.message); // 无法捕获内层抛出的异常
} finally {
console.log('[outer] finally');
}
/*
[inner] oops
[inner] finally
[outer] finally
*/