常见的AST节点

2,384 阅读2分钟

前言

学习AST,从认识AST的节点开始,虽然目前没有应用场景,但是认识认识总归是很好的。

1、literal(字面量)

比如let name = 'haha'中,haha就是一个StringLiteral。 常见的字面量有以下几种:

   let name = 'haha',   //haha ---> StringLiteral 字符串字面量。
   let name = `hehe`,   //hehe ---> TemplateLiteral 模版字面量。
   let age = 18,        //18   ---> NumberLiteral 数字字面量。

相应的还有 RegExpLiteral、BooleanLiteral、NullLiteral等等。

2、Identifier(标识符)

变量名、属性名、参数名等等一系列声明和引用的名字。 比如let name = 'haha'中,name就是一个Identifier。

3、Statement(语句)

语句是代码执行的最小单位。我们常见的有if语句、while语句、return语句等等。下面代码中每一行都是一个Statement

    break;
    continue; 
    return; 
    debugger; 
    throw Error(); 
    {} 
    try {} catch(e) {} finally{} 
    for (let key in obj) {} 
    for (let i = 0;i < 10;i ++) {} 
    while (true) {} 
    do {} while (true) 
    switch (v){case 1: break;default:;} 
    label: console.log(); 
    with (a){}

4、Declaration(声明语句)

声明语句是一种特殊的Statement,常见的声明语句有以下几种。

    const a = 1;   //VariableDeclaration
    function b(){} //FunctionDeclaration
    class C {}     //ClassDeclaration
    import d from 'e';  // ImportDeclaration
    export default e = 1; //ExportDefaultDeclaration
    export {e};    //ExportNamedDeclaration
    export * from 'e'; //ExportAllDeclaration

5、Expression(表达式)

expression的特点是执行完成后会有返回值,这也是它和语句的区别。 有的表达式可以独立作为语句执行,所以在解析时会在最外层加一个ExpressionStatement节点。 常见的表达式有以下几种:

    [1,2,3]       //ArrayExpression 数组表达式
    a = 1         //AssignmentExpression 赋值表达式
    1 + 2;        //二元表达式
    -1;           //一元表达式
    function(){}; //函数表达式
    () => {};     //箭头函数表达式
    class{};      //class表达式
    a;            //标识符
    this;         //this表达式
    super;        //super
    a::b;         //绑定表达式

6、class

class也有专门的AST节点表示,整个class的内容是ClassBody,属性是ClassProperty,方法是ClassMethod,通过kind区分时constructor还是普通方法。结构如下:

    class Koupou extends Person{ 
        name = 'koupou'; 
        constructor() {} 
        eat() {} 
    }

其ast节点结构如图所示:

class.jpg

7、Import

import有三种语法。

named import:

    import { a } from './a.js'

default import:

    import a from './a.js'

namespaced imort

    import * as a from './a.js'

这三种语法都对应ImportDeclaration节点,但是都有各自的Specifier属性,分别对应 ImportSpecifier、ImportDefaultSpecifer、ImportNameSpaceSpecifier。

8、Export

与Import相对应,Export也有三种,分别是:

named export

    export {
        a,
        b
    }

default export

    export default {}

all export

    export * from './a'

分别对应 ExportNamedDeclaration、ExportDefaultDeclaration、ExportAllDeclaration 的节点

其中 ExportNamedDeclaration 才有 specifiers 属性,其余两种都没有这部分(也比较好理解,export 不像 import 那样结构类似,这三种 export 语法结构是不一样的,所以不是都包含 specifier)。

9、Program & Directive

program 是代表整个程序的节点,它有 body 属性代表程序体,存放 statement 数组,就是具体执行的语句的集合。还有 directives 属性,存放Directive 节点,比如"use strict" 这种指令会使用 Directive 节点表示。 Program 是包裹具体执行语句的节点,而 Directive 则是代码中的指令部分。

10、File & Comment

babel 的 AST 最外层节点是 File,它有 program、comments、tokens 等属性,分别存放 Program 程序体、注释、token 等,是最外层节点。 注释分为块注释和行内注释,对应 CommentBlock 和 CommentLine 节点。

    /* 注释 */          块注释 CommentBlock
    // 注释             行注释 CommentLine

11、Modules

es module 是语法级别的模块规范,所以也有专门的 AST 节点。

总结

介绍了最常见的AST节点,并对相应节点进行了举例说明。有助于自己记忆以及理解AST的相关知识。