重学前端 20 # try里面放return,finally还会执行吗?

简介: 重学前端 20 # try里面放return,finally还会执行吗?

一、引言


本文讲一讲 JavaScript 语句。

8c09c8563c1d3c2ed7d8fcf04fdb3f49.jpg



二、Completion 类型


// return 执行了但是没有立即返回,而是先执行了finally
function kaimo(){
  try{
    return 0;
  } catch(err) {
    console.log(err)
  } finally {
    console.log("a")
  }
}
console.log(kaimo()); // a 0
// finally 中的 return 覆盖了 try 中的 return。
function kaimo(){
  try{
    return 0;
  } catch(err) {
    console.log(err)
  } finally {
    return 1;
  }
}
console.log(kaimo()); // 1


2.1、Completion Record


Completion Record 用于描述异常、跳出等语句执行过程。表示一个语句执行完之后的结果,它有三个字段。

   [[type]]:表示完成的类型,有 break、continue、return、throw、normal 几种类型

   [[value]]:表示语句的返回值,如果语句没有,则是 empty

   [[target]]:表示语句的目标,通常是一个 JavaScript 标签


JavaScript 使用 Completion Record 类型,控制语句执行的过程。



三、普通语句


JavaScript 中,把不带控制能力的语句称为普通语句。种类可以参考引言的图片。


1、这些语句在执行时,从前到后顺次执行(这里先忽略 var 和函数声明的预处理机制),没有任何分支或者重复执行逻辑。


2、普通语句执行后,会得到 [[type]] 为 normal 的 Completion Record,JavaScript 引擎遇到这样的 Completion Record,会继续执行下一条语句。


3、在 Chrome 控制台输入一个表达式,可以得到结果,但是在前面加上 var,就变成了 undefined。Chrome 控制台显示的正是语句的 Completion Record 的 [[value]]。


a39ccf8cf07ce47253c3dfb143dda317.png


四、语句块


语句块就是拿大括号括起来的一组语句,它是一种语句的复合结构,可以嵌套。


语句块内部的语句的 Completion Record[[type]] 如果不为 normal,会打断语句块后续的语句执行。

1、内部为普通语句的一个语句块:

// 在每一行的注释中为 Completion Record
{
    var i = 1; // normal, empty, empty
    i ++; // normal, 1, empty
    console.log(i) //normal, undefined, empty
} // normal, undefined, empty

在这个block中都是 normal 类型的话,该程序会按顺序执行。


2、加入 return


// 在每一行的注释中为 Completion Record
{
  var i = 1; // normal, empty, empty
  return i; // return, 1, empty
  i ++;
  console.log(i)
} // return, 1, empty

block 中产生的非 normal 的完成类型可以穿透复杂的语句嵌套结构,产生控制效果。




五、控制型语句


   控制型语句带有 if、switch 关键字,它们会对不同类型的 Completion Record 产生反应。


控制类语句分成两部分:


   对其内部造成影响:如 if、switch、while/for、try。

   对外部造成影响:如 break、continue、return、throw。


5f66f175c734a1f9f25526cd662494b8.png


穿透就是去上一层的作用域或者控制语句找可以消费break,continue的执行环境,消费就是在这一层就执行了这个break或者continue

这两类语句的配合,会产生控制代码执行顺序和执行逻辑的效果。




六、带标签的语句


1、任何 JavaScript 语句是可以加标签的,在语句前加冒号即可

firstStatement: var i = 1;


2、类似于注释,基本没有任何用处。唯一有作用的时候是:与完成记录类型中的 target 相配合,用于跳出多层循环。

    outer: while(true) {
        console.log("outer")
        inner: while(true) {
            console.log("inner1")
            break outer;
            console.log("inner2")
        }
    }
    console.log("finished")
    // outer  inner1  finished

https://tc39.github.io/ecma262/#sec-runtime-semantics


目录
相关文章
|
4月前
|
缓存 前端开发 JavaScript
一看就懂的gulp操作指南:让前端工作变得更加轻松(一)
一看就懂的gulp操作指南:让前端工作变得更加轻松
|
4月前
|
前端开发 JavaScript UED
一看就懂的gulp操作指南:让前端工作变得更加轻松(二)
一看就懂的gulp操作指南:让前端工作变得更加轻松
|
4月前
|
JavaScript 前端开发 API
一看就懂的gulp操作指南:让前端工作变得更加轻松(三)
一看就懂的gulp操作指南:让前端工作变得更加轻松
|
5月前
|
存储 C++
【C++】function包装器全解(代码演示,例题演示)
【C++】function包装器全解(代码演示,例题演示)
|
8月前
|
Java
(附运行结果和截图)关于try{return}finally中都有return 运行结果测试之旅
(附运行结果和截图)关于try{return}finally中都有return 运行结果测试之旅
|
11月前
|
算法
谈一谈|return None来看递归函数流程解析
谈一谈|return None来看递归函数流程解析
68 0
|
12月前
|
开发工具
游戏开发实战教程(5):重复执行和逻辑循环的区别
将循环分为重复执行和逻辑循环,应该是微信小游戏开发工具中所特有的。因为之前做游戏,无论是使用哪种工具或者哪种编程语言,对于循环来说,都只有一种,不会存在歧义或者误用。但是这里将循环分为了两种,如果误用的话会导致出现一些奇怪的问题。所以需要单独拿出来区分一下,避免掉进这个“坑”。
115 0
|
应用服务中间件 Apache nginx
Yii框架中的'enablePrettyUrl' => true, 这段代码是干什么的?底层原理是什么?为什么这样写?
Yii框架中的'enablePrettyUrl' => true, 这段代码是干什么的?底层原理是什么?为什么这样写?
119 0
|
前端开发
前端学习案例2-相等性判断2
前端学习案例2-相等性判断2
38 0
前端学习案例2-相等性判断2
因为一道题,我把 try-catch-finally 的细节都整理了一遍(1500字)
原因:return i++; 在内部是可以分为三步,① int tmp = i; ② i += 1; ③ return tmp;
67 0
因为一道题,我把 try-catch-finally 的细节都整理了一遍(1500字)