JavaScript执行(四):try里面放return,finally还会执行吗?

语句

常见的语句包括变量声明、表达式、条件、循环等。

Completion类型

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

  • [[type]]表示完成的类型,有break continue return throw和normal几种类型;
  • [[value]]表示返回的值,如果语句没有,则是empty;
  • [[target]]表示语句的目标,通常是一个JavaScript标签(标签在后文会有介绍)

JavaScript正是依靠语句的 Completion Record类型,方才可以在语句的复杂嵌套结构中,实现各种控制。
语句有几种分类:

普通语句

把不带控制能力的语句称为普通语句,普通语句有下面几种:

  • 声明语句

    • var声明
    • const声明
    • let声明
    • 函数声明
    • 类声明
  • 表达式语句
  • 空语句
  • debugger语句
    这些语句在执行时,从前到后用顺序执行,没有任何分支或重复执行逻辑。(我们先忽略var和函数声明的预处理逻辑)。
    普通语句执行后,会得到[[type]]为normal的Completion Record,JavaScript引擎遇到这样的Completion Record,会继续执行下一条语句。
    这些语句中,只有表达式语句会产生[[value]],当然,从引擎控制角度,这个value并没有什么用处。
    在chrome自带的调试工具,可以知道,输入一个表达式,在控制台可以得到结果,但是在前面加上var,就变成了undefined。

    Chrome控制台显示的正是语句的Completion Record的[[value]]。

    语句块

    语句块就是拿大括号括起来的一组语句,它是一种语句的复合结构,可以嵌套。
    语句块内部的语句的Completion Record的[[type]]如果不为normal,会打断语句块后续的语句执行。
    return语句可能产生return或者throw类型的Complatoon Record。

    {
    var i = 1; // normal, empty, empty
    i ++; // normal, 1, empty
    console.log(i) //normal, undefined, empty
    } // normal, undefined, empty

    在一个block中,如果每一个语句都是normal类型,那么他会顺利执行执行。
    如果在block中插入了一条return语句,会产生一个normal记录,那么整个block会变成为非normal。

    控制型语句

    控制型语句带有 if、switch关键字,它们会对不同类型的Completion Record产生反应。
    控制语句分为两部分:
    一类是对其内部造成影响,如if、switch、while/for、try。
    另一类是对外部造成影响如break、continue、return、throw,这两类语句的配合,会产生控制代码执行顺序和执行逻辑的效果,这也是我们编程的主要工作。

带标签的语句

语句的target字段
大部分时候,带标签的语句这个东西类似于注释,没有任何用处。唯一有作用的时候是:与完成记录类型中的target相配合,用于跳出多层循环。

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

break/continue 语句如果后跟了关键字,会产生带target的完成记录。一旦完成记录带了target,那么只有拥有对应label的循环语句会消费它。

因为JavaScript语句存在着嵌套关系,所以执行过程实际上主要在一个树形结构上进行, 树形结构的每一个节点执行后产生Completion Record,根据语句的结构和Completion Record,JavaScript实现了各种分支和跳出逻辑。

此文章为7月Day9学习笔记,内容来源于极客时间《重学前端》,日拱一卒,每天进步一点点💪💪

豪猪
4 声望4 粉丝

undefined