定义

首先来看下 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());
输出:

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

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());
输出

正如上图所示,这里打印的是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());
输出

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());

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







小小的声援一下,希望战'役'早日胜利。加油!

然后:

我会长期更新有趣的,有料的前端知识,如果对你有帮忙,请关注我,日后接受第一手更新消息。非常感谢







输出

你答对了没有?

可以看到,红框内为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 关键字之前执行。一图以概之:

最后,如果有帮到你的地方,欢迎关注、交流。

再问你一遍,你真的了解try..catch(finally)吗???的更多相关文章

  1. Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章

    原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...

  2. 求你了,再问你Java内存模型的时候别再给我讲堆栈方法区了…

    GitHub 4.1k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 4.1k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 4.1k Star 的 ...

  3. BCB一个问过100遍啊100遍的问题

    一个问过100遍啊100遍的问题作者: ---------- ,如转载请保证本文档的完整性,并注明出处.欢迎光临 C++ Builder 研究, http://www.ccrun.com/doc/go ...

  4. 拜托!面试请不要再问我Spring Cloud底层原理[z]

    [z]https://juejin.im/post/5be13b83f265da6116393fc7 拜托!面试请不要再问我Spring Cloud底层原理 欢迎关注微信公众号:石杉的架构笔记(id: ...

  5. Java 訪问权限控制:你真的了解 protected keyword吗?

    摘要: 在一个类的内部,其成员(包含成员变量和成员方法)是否能被其它类所訪问,取决于该成员的修饰词:而一个类是否能被其它类所訪问,取决于该类的修饰词.Java的类成员訪问权限修饰词有四类:privat ...

  6. vmware 安装配置 ,记住这一次不要再问我了。ok?

    Linux 安装配置 ,记住这一次不要再问我了.ok? 第一步 选择版本 如果遇到问题无法自动获取的  老男孩教育-李泳谊<youjiu_linux@qq.com> 17:51:43明天开 ...

  7. CDR X6打了3折,再送魔镜插件,是真的么?

    明人不说暗话,我.要.来.个.小.资.讯. CDR X6打了3折,再送魔镜插件,是真的么?   先来说说CorelDRAW,CorelDRAW众所周知,软件的确不便宜啊,对于个人来说,相当于一个高配苹 ...

  8. 面试官,不要再问我“Java GC垃圾回收机制”了

    Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解> ...

  9. 面试官,不要再问我“Java 垃圾收集器”了

    如果Java虚拟机中标记清除算法.标记整理算法.复制算法.分代算法这些属于GC收集算法中的方法论,那么"GC收集器"则是这些方法论的具体实现. 在面试过程中这个深度的问题涉及的比较 ...

随机推荐

  1. 1050 螺旋矩阵 (25 分)C语言

    本题要求将给定的 N 个正整数按非递增的顺序,填入"螺旋矩阵".所谓"螺旋矩阵",是指从左上角第 1 个格子开始,按顺时针螺旋方向填充.要求矩阵的规模为 m 行 ...

  2. 1042 字符统计 (20 分)C语言

    请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母, ...

  3. hadoop配置环境变量

    hadoop安装包解压 tar -xvf hadoop-2.7.7.tar.gz 解压成功ll查看文件 配置环境变量 1. vi  /home/wj/hadoop-2.7.7/etc/hadoop/h ...

  4. TypeScript 源码详细解读(1)总览

    TypeScript 由微软在 2012 年 10 月首发,经过几年的发展,已经成为国内外很多前端团队的首选编程语言.前端三大框架中的 Angular 和 Vue 3 也都改用了 TypeScript ...

  5. a标签属性href值为#和javasrcript:void(0)的区别

    当我们需要一个空链接时,通常有两种方法: <a href="#">这个一个空链接</a> <a href="javascript:void( ...

  6. python类型检查和类型转换

    类型检查 type()用来检查值的类型 (整型.浮点型.布尔值.字符串.空值) 该函数会将检查的结果作为返回值返回,可以通过变量来接收函数的返回值 print(type(1)) # <class ...

  7. Spring Boot2 系列教程(二十一) | 自动配置原理

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 这个月过去两天了,这篇文章才跟大家见面,最近比较累,大家见谅下.下班后闲着无聊看了下 SpringBoot 中的自动配置,把我 ...

  8. 机器学习-特征工程-Missing value和Category encoding

    好了,大家现在进入到机器学习中的一块核心部分了,那就是特征工程,洋文叫做Feature Engineering.实际在机器学习的应用中,真正用于算法的结构分析和部署的工作只占很少的一部分,相反,用于特 ...

  9. RocketMQ客户端加载流程

     这节介绍RocketMQ客户端的启动流程,即Consumer和Producer的启动流程. 1. 客户端demo  首先先看下客户端的demo Producer: public class Sync ...

  10. 怎么将文件夹上传到GitHub上

    1. 在GitHub上新建一个仓库地址: http://github.com/......git 2. 在需要上传的文件夹目录下,运行 git   init  初始化git: 3. 运行git  ad ...