throw/try/catch/finally 语句
异常:发生了某种异常情况或错误时产生的一个信号。
抛出异常:用信号通知发生了错误或异常状况。(使用
throw
语句)捕获异常:采取必要的手段处理这个信号。(使用
catch
语句)
throw/try/catch/finally 语句
throw 语句作用:显式地抛出异常。
throw 语法:throw exception;
(exception
的值是任意类型)
try/catch/finally 语句是 JS 的异常处理机制。
try:定义了需要处理的异常所在的代码块。
catch:当 try
块内某处发生了异常时,调用 catch 内的代码逻辑。
finally:不管 try
块中是否发生异常,finally 块内的逻辑总是执行。
注意:
catch
从句和finally
从句是可选的,但try
从句需要至少两者之一组成完整的语句。也就是说,try
从句不能单独存在。
JS 解析器抛出异常的时候通常采用 Error 类型或其子类型。Error 的 name
属性表示错误类型,message
属性表示错误的提示信息。
function fun(x) {
// 如果输入参数是非法的,则抛出一个异常
if (x < 0) throw new Error('x 不能是负数')
return x
}
fun(-1);
上面代码中,输入的
x
是非法的,程序通过throw
语句显示的抛出一个异常。
当抛出异常时,JS 解析器会立即停止当前正在执行的逻辑,并跳转至最近的异常处理程序。
function fun(x) {
try {
if (x < 0) {
console.log('第4行:此行代码可以执行...')
throw new Error('发生异常...')
console.log('第6行:此行代码无法执行...')
}
} catch (e) {
console.log('第9行:异常在此被捕获--' + e)
}
}
fun(-1)
上面代码中,由于
throw
从句会抛出一个异常并停止正在执行的逻辑,所以第6行不会被执行。抛出的异常会被catch
从句捕获并处理。
如果抛出异常的代码块没有相关联的 catch
从句,解析器会检查更高层的闭合代码块是否有异常处理程序。以此类推,直到找到异常处理程序为止。否则,JS 会把该异常当做程序错误来处理,并报告给用户。
function fun1 (x) {
if (x < 0) {
throw new Error('此异常发生在 fun1 中...')
}
}
function fun2 (x) {
try {
fun1(x);
} catch (e) {
console.log('在 fun2 中处理异常:' + e)
}
}
fun2(-1)
上面代码中,
fun2
在 内部中调用了fun1
。程序在fun1
中抛出异常,但是该代码块中没有异常处理程序,解析器会向上一层(fun2
)代码块中检查,所以异常会被fun2
中的catch
从句捕获并处理。
不管是 try
从句中是否产生异常,finally
从句内的逻辑总是会执行。
function fun () {
try {
console.log('try')
} finally {
console.log('finally')
}
}
fun()
上面代码中,
try
从句中的逻辑不发生异常,之后会接着执行finally
从句中的逻辑。
如果在 try
从句中发生了异常,并存在相关联的局部 catch
从句,解析器会先执行 catch
从句中的逻辑,然后执行 finally
从句中的逻辑。
function fun () {
try {
throw new Error('try 中发生异常...')
} catch (e) {
console.log('在 catch 中捕获异常:' + e);
} finally {
console.log('finally: 我都会被执行')
}
}
fun()
上面代码中,
try
从句中抛出异常,被局部catch
从句捕获并处理,接着执行finally
从句中的逻辑。
如果不存在处理异常的局部 catch
从句,解析器会首先执行 finally
中的逻辑,然后向上传播这个异常,直到找到能处理这个异常的 catch
从句。
function fun1 () {
try {
throw new Error('try:不行了,我要抛出异常了...')
} finally {
console.log('finally:先执行我,再传播异常...')
}
}
function fun2 () {
try {
fun1()
} catch (e) {
console.log('catch:嘻嘻,又捕获到一个小笨蛋--' + e)
}
}
fun2()
上面代码中,
try
从句中抛出异常,但没有局部catch
从句处理异常,所以会先执行finally
从句,然后被上一层的catch
从句捕获。
当由于 return
、continue
或 break
语句使得解析器跳出 try
从句时,解析器在执行新的目标代码之前会先执行 finally
从句中的逻辑。
function fun1 () {
try {
return 'cez'
} finally {
console.log('finally: 在执行新的目标代码之前,会先执行我哦...')
}
}
function fun2 () {
fun1()
console.log('新的目标代码:我执行在 finally 从句之后哦...')
}
fun2()
如果在 try
和 finally
从句中都抛出异常,finally
中的异常将替代 try
中的异常。
function fun1 () {
try {
throw new Error('在 try 中抛出异常...')
} finally {
throw new Error('在 finally 中抛出异常...')
}
}
function fun2 () {
try {
fun1()
} catch (e) {
console.log('catch:'+ e)
}
}
fun2()
如果 finally
从句中有 return
语句,尽管抛出了异常并且这个异常还没有处理,但这个方法依然会正常返回。
function fun1 () {
try {
throw new Error('在 try 中抛出异常...')
} finally {
return 'finally'
}
}
function fun2 () {
try {
console.log(fun1())
} catch (e) {
console.log('catch:' + e)
}
}
fun2()
如果
finally
中有return
语句,则该方法会有正常的返回值,并且try
中抛出的异常将不会被更高层的catch
从句捕获到,但会被局部的catch
从句捕获,如下:
function fun1 () {
try {
throw new Error('在 try 中抛出异常...')
} catch (e) {
console.log('局部 catch:' + e)
} finally {
return 'finally'
}
}
function fun2 () {
console.log(fun1())
}
fun2()
此时
try
中抛出的异常会被局部catch
从句捕获。
下一篇: ai中怎么绘制立体的3d物体模型?
推荐阅读