携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
表达式(Expression)
表达式的特点是执行完以后有返回值,这是和语句 (statement) 的区别。
| 表达式名称 | 代码 | 节点 |
|---|---|---|
| 数组表达式 | [1,2,3] | ArrayExpression |
| 赋值表达式 | a = 1 | AssignmentExpression |
| 二元表达式 | 1+2 | BinaryExpression |
| 一元表达式 | -1 | UnaryExpression |
| 普通函数表达式 | function(){} | FunctionExpression |
| 箭头函数表达式 | ()=>{} | ArrowFunctionExpression |
| 类表达式 | class{} | ClassExpression |
| 标识符 | a | Identifler |
| this | this | ThisExpression |
| super | super | Super |
| 绑定表达式 | a::b | BindExpression |
绑定运算符 ::
双冒号绑定运算符 :: 是函数 bind 的简写形式;
运算符的左边是一个对象,右边是一个函数,运算符会字段将左边的对象作为右边函数的上下文环境(即右边函数中的this指向左边的对象)
const foo = {}
function bar(){}
foo::bar // 等同于 bar.bind(foo)
绑定运算符也可以带参数
foo::bar(...arguments) // 等同于 bar.apply(foo, arguments)
如果运算符左边的对象为空,右边是一个对象的方法,则等同于将该方法绑定到该对象上
const log = ::console.log;
// const log = console.log.bind(console)
这个运算符好像还在提案阶段,我在控制台试了一下用不了
identifier和super
这两个家伙之所以是表达式,是因为它们俩有返回值,而前面也说了,表达式的特点就是执行完有返回值,它俩符合这个特点,所以它俩是表达式。
从上面这种结果可以看出,当我们判断某个AST节点的类型的时候,要看它是否符合该种类型的特点。
要注意的就是,类型并不是一层不变的, 比如说有些表达式可以单独执行(赋值表达式、数组表达式),符合语句的特点,所以它的类型也可以是语句。有些表达式则不可以单独执行(匿名函数表达式、匿名class表达式),它们单独执行的话就会报错,需要和其他类型的节点组合在一起构成语句(比如说构成赋值语句)。
当表达式作为语句被执行的时候,解析出来的AST如下所示(以赋值表达式 a=1 为例):
解析出来的AST包裹一层 ExpressionStatement节点 表示这个表达式被当作语句执行的。