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 标签(标签在后文会有介绍)。
普通的语句
- 声明类语句
- 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
控制型语句
编程逻辑实现很重要的一个部分。