for (let i = 0; i < 100; i++) {if (i === 50) break;
}
置信大家在应用 break
的场景是相似下面的场景,在 for 循环中在特定的判断下跳出循环。
置信大家都在 console 上这样操作过,输出这些语句的后果到底是什么。
答案是 Completion Record
Completion Record
是 EMCScript 规范中的一个标准类型。
它长这个样子
{[[Type]]: normal | continue | break | return | throw
[[Value]]: 语句执行的后果,如果没有则是 empty
[[Target]]: 控制流的转移指标,通常是标签
}
语句的执行都会产生一个 Completion Record
在一个 Block 中,也会返回一个Completion Record
{
let a = 1; // 1
console.log(a); // 2
++2; // 3
console.log(a); // 4
}
大家间接把下面的代码复制在 chrome 的 console 中而后执行,看后果是什么?
后果是 2
,当初咱们逐渐剖析一下
在下面的块级作用域中,地位 1 产生的 Completion Record
是
[[Type]]: normal,
[[Value]]: empty,
[[target]]: nothing
依照下面的逻辑,地位 2 的 [[Value]]
是 empty
地位 3 的 [[Value]]
是 2
地位 4 的 [[Value]]
是 empty
empty 不会笼罩之前的后果
所以整个块级作用域的执行后果是 2
当初有一个提案是 do 表达式
const w = do {
let a = 1;
++2;
};
可能获取块级作用域 Completion Record
的[[Value]]
如果这个提案通过的话,之后的 JSX 将摈弃长长的三目判断
下面这个代码,如果执行 foo 函数输入的内容是什么?
在 try 中进行 return,因为存在 finally,而 finally 无论如何都是须要被执行的,所以 try 的 Completion Record
是
[[Type]]: return,
[[Value]]: 100,
[[target]]: nothing
执行到 finally 的时候,整个 try-catch-finally 代码块的 Completion Record
是
[[Type]]: break,
[[Value]]: empty,
[[target]]: bbb
所以 return 会被 break 笼罩
最终返回的 i 是 101