再问你一遍,你真的了解try..catch(finally)吗???
定义
首先来看下 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)吗???的更多相关文章
- Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章
原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...
- 求你了,再问你Java内存模型的时候别再给我讲堆栈方法区了…
GitHub 4.1k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 4.1k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 4.1k Star 的 ...
- BCB一个问过100遍啊100遍的问题
一个问过100遍啊100遍的问题作者: ---------- ,如转载请保证本文档的完整性,并注明出处.欢迎光临 C++ Builder 研究, http://www.ccrun.com/doc/go ...
- 拜托!面试请不要再问我Spring Cloud底层原理[z]
[z]https://juejin.im/post/5be13b83f265da6116393fc7 拜托!面试请不要再问我Spring Cloud底层原理 欢迎关注微信公众号:石杉的架构笔记(id: ...
- Java 訪问权限控制:你真的了解 protected keyword吗?
摘要: 在一个类的内部,其成员(包含成员变量和成员方法)是否能被其它类所訪问,取决于该成员的修饰词:而一个类是否能被其它类所訪问,取决于该类的修饰词.Java的类成员訪问权限修饰词有四类:privat ...
- vmware 安装配置 ,记住这一次不要再问我了。ok?
Linux 安装配置 ,记住这一次不要再问我了.ok? 第一步 选择版本 如果遇到问题无法自动获取的 老男孩教育-李泳谊<youjiu_linux@qq.com> 17:51:43明天开 ...
- CDR X6打了3折,再送魔镜插件,是真的么?
明人不说暗话,我.要.来.个.小.资.讯. CDR X6打了3折,再送魔镜插件,是真的么? 先来说说CorelDRAW,CorelDRAW众所周知,软件的确不便宜啊,对于个人来说,相当于一个高配苹 ...
- 面试官,不要再问我“Java GC垃圾回收机制”了
Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解> ...
- 面试官,不要再问我“Java 垃圾收集器”了
如果Java虚拟机中标记清除算法.标记整理算法.复制算法.分代算法这些属于GC收集算法中的方法论,那么"GC收集器"则是这些方法论的具体实现. 在面试过程中这个深度的问题涉及的比较 ...
随机推荐
- 洛谷$P5329\ [SNOI2019]$字符串 字符串
正解:字符串 解题报告: 传送门$QwQ$ 有两个很妙的方法,分别港下$QwQ$ 首先为了表示方便,这里和题面一样设$s_i$表示去掉第$i$个字母得到的字符串.另设$lcp(i,j)$表示$suf_ ...
- Linux 学习笔记 2 Centos 安装与网络的配置以及VI编辑器的使用
前言 当然,还是觉得Centos 在众多的Linux 发行版中,还是很有地位的,好多的服务器大多沿用的都是一代的Centos 因为它开源(这是废话)而且稳定,这才是服务器沿用的最重要的一项指标. 镜像 ...
- java 多线程 快速入门
------------恢复内容开始------------ java 多线程 快速入门 1. 进程和线程 什么是进程? 进程是正在运行的程序它是线程的集合 进程中一定有一个主线程 一个操作系统可以有 ...
- 小米6X谷歌套件
话不多说真机测试完美适配,安卓万物基于谷歌链接如下(个别MIUI版本不同谷歌商店会报错,如遇到请留言我会第一时间回复解决) 链接:https://pan.baidu.com/s/1b2Cs0u9J2b ...
- Java开发中的各种乱码问题
乱码问题 其实解决乱码问题,就是保证所有的编码格式一致,就不会出现问题. 控制台乱码 修改idea的控制台格式 修改 idea.exe.vmoptions和idea64.exe.vmoptions 在 ...
- cogs 1583. [POJ 3237] 树的维护 树链剖分套线段树
1583. [POJ 3237] 树的维护 ★★★★ 输入文件:maintaintree.in 输出文件:maintaintree.out 简单对比时间限制:5 s 内存限制:128 ...
- TypeScript 源码详细解读(3)词法2-标记解析
在上一节主要介绍了单个字符的处理,现在我们已经有了对单个字符分析的能力,比如: 判断字符是否是换行符:isLineBreak 判断字符是否是空格:isWhiteSpaceSingleLine 判断字符 ...
- NTT 求原根
使用NTT需要保证模数mod 为质数. 通过以下代码求得一个模数的原根 , 常见的质数的原根 998244353 -> 3 1e9+7 -> 5 #include<bits/ ...
- iOS使用fastlane自动化打包到fir(最全最详细流程)
# iOS使用fastlane自动化打包到fir(最全最详细流程)1. **首先确认是否安装了ruby,终端查看下ruby版本**> ruby -v终端输出:ruby 2.4.1p111 (20 ...
- DirectX11 Windows Windows SDK--28 计算着色器:波浪(水波)
前言 有关计算着色器的基础其实并不是很多.接下来继续讲解如何使用计算着色器实现水波效果,即龙书中所实现的水波.但是光看代码可是完全看不出来是在做什么的.个人根据书中所给的参考书籍找到了对应的实现原理, ...