zoukankan      html  css  js  c++  java
  • 再问你一遍,你真的了解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 关键字之前执行。一图以概之:

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

  • 相关阅读:
    如何理解对象、属性、方法?
    添加超链接,请始终将正斜杠添加到子文件夹
    什么导致table不稳固?
    HTML css和js浏览器兼容问题
    理解前端数据双向绑定原理——Object.defineProperty()
    Js事件传播流程
    移动端开发项目注意事项
    get与post的区别
    Web 页面性能优化与SEO优化
    我的WCF项目系列之二WCF初级应用
  • 原文地址:https://www.cnblogs.com/xiaoyuxy/p/12297701.html
Copyright © 2011-2022 走看看