一. Completion Record(完成记录)
表达式返回的值在内部叫Completion Record,是一个内部对象,它有如下属性
键 | 值 | 描述 |
---|---|---|
[[type]] |
normal, break, continue, retur, throw |
完成的类型,用于描述控制流 |
[[value]] |
字符串或空(empty) | 产生的值 |
[[target]] |
字符串或空(empty) | 控制流的转移目标,类似于goto break,continue加标签可以转移到指定层 |
二. BlockStatement(语句块)
语句块,可以形成一个新的词法环境
Completion Record如下[[type]]:normal
{
...
}
三. Iteration
- 循环的类型Completion Record可以是break或continue,加标签可以转移到指定层;
- 只有循环/swicth识别并消费标签语句
- LabelledStatement
- IterationStatement
- continueStatement
- BreakStatement
- SwitchStatement
[[type]]: break, continue
[[target]]: label
- 以下是循环的语法
while
do while
for
for in
for of
for await of
1. for
for声明可以独立的产生作用域,范围在for语句的block之外;这里i只声明了一次 ```javascript /* 这里打印10个0,每次循环使用的外面的i / for(let i = 0; i < 10; i++) { let i = 0 console.log(i); }
/ 理解,类似于如下的代码 */ { / 这是for产生的作用域 / let i = 1; console.log(i); { /** 这里是for{}内的环境 / let i = 0; console.log(i); } }
<a name="nIVzA"></a>
### 2. for of
1. 可以循环数组的值
1. 任何能有迭代的对象都可以循环,如可以循环generator函数
示例如下
```javascript
function *p() {
yield 0;
yield 1;
yield 2;
}
for(let i of p()) {
console.log('i :>> ', i);// 0 1 2
}
3. for in
4. Label语法
类似于goto,可以解决break双层循环的问题,性能没有问题。
四. try catch
try…catch语法的Completion Record如下[[type]]:return
[[target]]:label
try {
throw 2;
} catch(e) {
let e;
console.log(e);
}
五. 声明
- FunctionalDeclaration 函数声明
- GeneratorDeclaration Generator声明
- AsyncFunctionDeclaration 异步
- AsyncGeneratorDeclaration 异步Generator
- VariableStatement 变量声明
- ClassDeclaration class声明
- LexicalDeclaration
1. 异步Generator
可以for await of调用 ```javascript /* 一秒输出一个自增的数 / function sleep(d) { return new Promise((resolve) => setTimeout(resolve, d)); }
async function *p() { let i = 0; while(true) { await sleep(1000); yield ++i; } }
for await (let i of p()) { console.log(‘i :>> ‘, i); }
<a name="cXH0U"></a>
### 2. 变量声明
1. var声明的范围:**函数**;
在编译阶段,所有的var声明和函数声明会被放在词法环境中Lexical Environment,var 变量初始化一个`undefined`值。function声明同理,初始化成一个函数。<br />为什么var声明的范围会在函数部分:<br />因为词法环境是执行上下文的一部分(可以把执行上下文看成是一个对象,词法环境是一个属性),js引擎每调用一个函数便创建执行上下文并压入执行上下文栈中。<br />参考:[详解ES6执行时词法环境/作用域/执行上下文/执行栈和闭包](https://juejin.cn/post/6926831181681917959)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23168078/1646669581876-b4147780-0693-48f0-9f83-7ca1d2ee6741.png#clientId=u4a17f202-7d28-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=334&id=u26337fb1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1000&originWidth=1466&originalType=binary&ratio=1&rotation=0&showTitle=false&size=115991&status=done&style=none&taskId=u3c6e292e-ccce-4da2-b22f-5efd6e0edbd&title=&width=490.36358642578125)
```javascript
console.log(name); // undefined
var name = 'a';
console.log(name); // a
/** js引擎内部,编译阶段 */
lexicalEnvironment = {
name: undefined
}
/** js引擎内部,执行阶段 */
lexicalEnvironment = {
name: 'a'
}