前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【JS】852- 再学一遍 try...catch

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

作者头像
pingan8787
发布2021-02-26 16:25:44
1.1K0
发布2021-02-26 16:25:44
举报
文章被收录于专栏:前端自习课前端自习课

定义

首先来看下 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

代码语言:javascript
复制
function fn() {
  try {
    console.log('try块内log');
  } catch (error) {
    console.log('catch块内log');
  } finally {
    console.log('finally块内log====');
  }
  return '一般情况下的return';
}
console.log(fn());

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

case2

代码语言:javascript
复制
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());

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

case3

代码语言:javascript
复制
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());

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

你以为这样就结束了吗?

我们继续往下看。

case4

代码语言:javascript
复制
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());

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

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

应用场景

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

代码语言:javascript
复制
function hoc(fn) {
  return fn()
}

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

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

代码语言:javascript
复制
function hoc(fn) {
  const res = fn();
  // 其他操作
  return res;
}
  • 很简答,我们可以先获取返回值,再进行其他操作,然后return
  • 不过这样我们就占用了额外的空间,而且无法便利的复用return后的语句,这个时候,我们的try...catch就可以排上用场了:
代码语言:javascript
复制
function hoc(fn) {
  try {
    return fn();
  } finally {
    // 一些其他操作,这些操作会在 `fn()执行后,return执行前` 被执行
  }
}

总结

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端自习课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义
  • case1
  • case2
  • case3
  • case4
  • 应用场景
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档