try catch finally 执行顺序与抛错机制
try catch finally 执行顺序与抛错机制
一、结论
-
try 先执行
,若有报错,执行 catch -
不管有没有异常 finally 肯定会执行
-
try 和 catch 中
存在 return 或者 throw
,finally 也会执行
-
catch 中若报错:
猜测先暂存 catch 错误
,等待 finally 执行完毕后,抛出错误 -
catch 中若报错, finally 也报错:
- 猜测先
暂存 catch 错误
,等待 finally 执行,发现 finally 存在错误,直接抛出 finally 的错误
- 抛出 catch 错误的程序不会执行,所以最终表示为
抛出 finally 错误,catch 错误不显示
- 猜测先
-
在 try catch 中,如果碰到 return 语句:
- 先执行
return 语句表达式
,但是执行结果会被局部变量
暂存 - 之后执行 finally 内容,再执行 return 操作,
返回 局部变量暂存 的结果
- 先执行
-
try 或 catch 若有 return :
暂存 return 的执行结果
,等待 finally 执行完毕后,才返回 try 或 catch 中return 的执行结果
-
try 或 catch 若有 return ,finally 也有 return:
暂存 try 和 catch return 的执行结果
,等待 finally 执行完毕- finally 存在 return ,
直接返回 finally 的 return 值,程序提前退出
二、场景
throw 的作用是手动中断程序,抛出一个异常,会被捕获
以下的
制造一个异常
场景可以视为throw 一个常量或者其他数据
,所以 throw 的场景等同异常场景
1、无错误情况
1、正常执行
2、在 try 中 return 一个 常量
3、在 try 中 return 一个 常量, 在 finally 中 return 一个 常量
2、有错误情况
1、在 try 中 制造一个异常
2、在 try、catch 中 各制造一个异常
3、在 try、catch、finally 中 各制造一个异常
4、在 try 中 制造一个异常, catch return 一个 常量
5、在 try 中 制造一个异常, catch return 一个 常量,finally return 一个常量
三、测试代码
以下测试用例都执行
console.log(test())
1、正常执行
let test = function() {
try {
console.log('try:>>', 1)
} catch (e) {
console.log('catch:>> ', e)
} finally {
console.log('finally:>> ')
}
}
// 没有报错,正常输出
// try:>> 1
// finally:>>
// undefined
2、在 try 中 return 一个 常量
- try 中 return 的结果被 局部变量 保存起来,执行 finally 之后再输出
let test = function() {
try {
// 未定义 a
console.log('try:>>', 1)
return 2
} catch (e) {
console.log('catch:>> ', e)
} finally {
console.log('finally:>> ')
}
}
// try:>> 1
// finally:>>
// 2
3、在 try 中 return 一个 常量, 在 finally 中 return 一个 常量
- try return 的值被 局部变量 保存起来,执行 finally 之后,
- 发现 finally 中存在 return ,直接 返回 finally 的 return 结果,程序提前退出
let test = function() {
try {
console.log('try:>>', 1)
return 2
} catch (e) {
console.log('catch:>> ', e)
} finally {
console.log('finally:>> ')
return 3
}
}
// try:>> 1
// finally:>>
// 3
4、在 try 中 制造一个异常
- try 异常被 catch 捕获,输出 try 异常,继续执行 finally
let test = function() {
try {
console.log('try:>>', a)
} catch (e) {
console.log('catch:>> ', e)
} finally {
console.log('finally:>> ')
}
}
// catch:>> ReferenceError: a is not defined
// finally:>>
// undefined
5、在 try、catch 中 各制造一个异常
- try 异常被 catch 捕获,此时catch 异常,猜测先
暂存 catch 错误
,等待 finally 执行完毕后,抛出 catch 错误
let test = function() {
try {
console.log('try:>>', a)
} catch (e) {
console.log('catch:>> ', e)
console.log('catch:>> ', b)
} finally {
console.log('finally:>> ')
}
}
// catch:>> ReferenceError: a is not defined
// finally:>>
// ReferenceError: b is not defined
6、在 try、catch、finally 中 各制造一个异常
- try 异常被 catch 捕获,此时 catch 异常,猜测先
暂存 catch 错误
,等待 finally 执行,发现 finally 存在错误,直接抛出 finally 的错误
- 抛出 catch 错误的程序不会执行,所以最终表示为
抛出 finally 错误,catch 错误不显示
let test = function() {
try {
console.log('try:>>', a)
} catch (e) {
console.log('catch:>> ', e)
console.log('catch:>> ', b)
} finally {
console.log('finally:>> ')
console.log('finally:>> ', c)
}
}
// catch:>> ReferenceError: a is not defined
// finally:>>
// ReferenceError: c is not defined
7、在 try 中 制造一个异常, catch return 一个 常量
- try 异常被 catch 捕获,
局部变量暂存 catch return 的执行结果
, - 执行 finally 之后,返回
局部变量暂存的结果
let test = function() {
try {
console.log('try:>>', a)
} catch (e) {
console.log('catch:>> ', e)
return 1
} finally {
console.log('finally:>> ')
}
}
// catch:>> ReferenceError: a is not defined
// finally:>>
// 1
8、在 try 中 制造一个异常, catch return 一个 常量,finally return 一个常量
- try 异常被 catch 捕获,
局部变量暂存 catch return 的执行结果
,等待 finally 执行完毕 - finally 存在 return ,
直接返回 finally 的 return 值,程序提前退出
let test = function() {
try {
console.log('try:>>', a)
} catch (e) {
console.log('catch:>> ', e)
return 1
} finally {
console.log('finally:>> ')
return 2
}
}
// catch:>> ReferenceError: a is not defined
// finally:>>
// 2
9、验证 try return 后,结果暂存,执行 finally 后,最后返回暂存结果
let test = function() {
let x = 1
try {
// 此处 执行 ++x 表达式, x = 2,但是程序不会直接返回结果
// 而是会使用 局部变量 缓存 return 的值 2
// 等待 finally 执行完成后,再 return 缓存的 局部变量值
return ++x
} catch (e) {
} finally {
// 这里 x = 3
// x 变成了 3,但是最终函数执行的返回值是 2
++x
}
// 因为上面 return ,此处不执行
console.log('x :>> ', x);
return x
}
// 最后输出结果为: 2
// 分析:
// 1、
// try 执行 ++x 表达式, x = 2,但是程序不会直接返回结果
// 而是会使用 局部变量 缓存 return 的值 2
// 2、
// 执行 finally
// x = 3
// 3、
// finally 执行完成后, return 缓存的 局部变量值 2
// 最后输出结果为 2
都读到最后了、留下个建议如何