0
点赞
收藏
分享

微信扫一扫

【JS】852- 再学一遍 try...catch

【JS】852- 再学一遍 try...catch_javascript

定义

首先来看下 MDN 的定义:

The try...catch statement marks a block of statements to try and specifies a response should an exception be thrown.

​try...catch​​语句标记要执行的语句,并指定一个当有异常抛出时候的响应

简短的一句的确描述了​​try...catch​​的大部分功能。

但是,最​​MDN​​的最后,有一段话是这么写的:

Returning from a finally-block

If the finally-block returns a value, this value becomes the return value of the entire try-catch-finally statement, regardless of any return statements in the try and catch-blocks. This includes exceptions thrown inside of the catch-block:

​finally​​语句块的返回值

如果​​finally​​​语句块中有返回值,那么这个值将作为整个​​try...catch​​​语句的返回,无论​​try​​​语句块或者​​catch​​​语句块中是否有返回,这包括了​​catch​​中的异常。

ok,那我们就尝试加上​​return​​,看看会发生什么。

case1

function fn() {
try {
console.log('try块内log');
} catch (error) {
console.log('catch块内log');
} finally {
console.log('finally块内log====');
}
return '一般情况下的return';
}
console.log(fn());

【JS】852- 再学一遍 try...catch_ide_02

一切看起来都如我们所想,没有问题,继续往下看。

case2

function fn() {
try {
console.log('try块内log');
return 'try中的return'; // <=== 多了这么一句
} catch (error) {
console.log('catch块内log');
return 'catch中的return语句';
} finally {
console.log('finally块内log====');
}
return '一般情况下的return';
}
console.log(fn());

【JS】852- 再学一遍 try...catch_javascript_03

正如上图所示,这里打印的是​​try​​​的​​return​​​,但是,​​finally​​​语句块中的​​log​​​依然被执行了。看到这里,我们可以知道,​​finally​​​的执行时机是在​​try​​​(或者​​cache​​​,​​cache​​​同理)执行​​return​​​之前被执行。那我们就可以验证下MDN上所说的:​​finally​​语句块的返回值 这句话的真正含义。

case3

function fn() {
try {
console.log('try块内log');
return 'try中的return'
} catch (error) {
console.log('catch块内log');
return 'catch中的return语句';
} finally {
console.log('finally块内log====');
return 'finaly中的return'; // <=== 多了这么一句
}
return '一般情况下的return';
}
console.log(fn());

【JS】852- 再学一遍 try...catch_ide_04

ok,依然很正常,因为​​finally​​​会在try的​​return​​​之前执行,所以拦截了​​try​​​中的​​return​​​,打印了​​finally​​​中的​​return​​。

你以为这样就结束了吗?

我们继续往下看。

case4

function justLog(){
console.log('来自justLog的打印');
return '来自justLog的return'
}

function fn() {
try {
console.log('try块内log');
return justLog(); // <=== 这次我们return了一个函数
} catch (error) {
console.log('catch块内log');
return 'catch中的return语句';
} finally {
console.log('finally块内log====');
return 'finaly中的return';
}
return '一般情况下的return';
}
console.log(fn());

先思考一下会打印什么?看看是否和真实的输出一致。给我们几秒钟...

【JS】852- 再学一遍 try...catch_高阶函数_05

  • 可以看到,红框内为​​justLog​​函数的​​log​​,红框下面是​​finally​​中的打印和返回。
  • 所以​​finally​​真正的执行时机是:​​try​​(或​​catch​​)中 ​​return​​关键字之前。
  • 所以我们才看到了​​justLog​​中的打印。
  • 有关​​return​​关键字的实现,可以自行查询标准,这里不赘述。

应用场景

比如我们有这样一个高阶函数:

function hoc(fn) {
return fn()
}

我们想要返回所传递参数的执行结果,这样做是没问题的。

那如果我们想在函数执行之后,​​return​​之前,做一些其他操作,应该怎么做呢?

function hoc(fn) {
const res = fn();
// 其他操作
return res;
}

  • 很简答,我们可以先获取返回值,再进行其他操作,然后​​return​​。
  • 不过这样我们就占用了额外的空间,而且无法便利的复用​​return​​后的语句,这个时候,我们的​​try...catch​​就可以排上用场了:

function hoc(fn) {
try {
return fn();
} finally {
// 一些其他操作,这些操作会在 `fn()执行后,return执行前` 被执行
}
}

总结

大白话来讲,​​finally​​​语句块会在​​try​​​(或​​catch​​​)中的 ​​return​​ 关键字之前执行。一图以概之:

【JS】852- 再学一遍 try...catch_javascript_06

【JS】852- 再学一遍 try...catch_高阶函数_07

举报

相关推荐

0 条评论