JavaScript执行运行时 再解(四)

Completion

function foo(){
  try{
    return 0;
  } catch(err) {

  } finally {
    console.log("a")
  }
}

console.log(foo());
// return 执行 console 输出

虽然 return 执行了,但是函数并没有立即返回,又执行了 finally 里面的内容,这样的行为违背了很多人的直觉。

在看下一段代码,在 finally 里面加入 return 语句

function foo(){
  try{
    return 0;
  } catch(err) {

  } finally {
    return 1;
  }
}

console.log(foo());
// return 1执行(覆盖了 return 0),console 输出

这一机制就是Completion Record,用于描述异常、跳出等语句的执行过程。

Completion Record

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

98ce53be306344c018cddd6c083392d5

普通的语句
  • 声明类语句
    • var
    • const
    • let
    • function
    • class
  • 表达式语句
  • 空语句
  • debugger 语句

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

语句块

一种语句的复合结构,可以嵌套。

语句块本身并不复杂,我们需要注意的是语句块内部的语句的 Completion Record 的[[type]] 如果不为 normal,会打断语句块后续的语句执行。

比如我们考虑,一个[[type]]为 return 的语句,出现在一个语句块中的情况。

{
  var i = 1; // normal, empty, empty
  i ++; // normal, 1, empty
  console.log(i) //normal, undefined, empty
} // normal, undefined, empty
{
  var i = 1; // normal, empty, empty
  return i; // return, 1, empty
  i ++; 
  console.log(i)
} // return, 1, empty
控制型语句

编程逻辑实现很重要的一个部分。 7760027d7ee09bdc8ec140efa9caf1d3

posted @ 2020-06-18 11:24  jaiodfjiaodf  阅读(177)  评论(0编辑  收藏  举报