AST(Abstract Syntax Tree,抽象語法樹)

AST(Abstract Syntax Tree,抽象語法樹)

在計算機科學中,抽象語法樹(Abstract Syntax Tree, AST),是源代碼語法結構的一種抽象表示。它以樹狀的形式表現編程語言的語法結構,樹上的每個節點都表示源代碼中的一種結構。之所以說語法是“抽象”的,是因爲這裏的語法並不會表示出真實語法中出現的每個細節。

ECMAScript 當然也有對應的抽象語法樹(下面都稱 AST),今天我們就來解析一下 ECMAScript,看看在 AST 中我們的代碼將會如何展示。

本文借鑑了 使用 Acorn 來解析 JavaScript,本文同樣使用 acorn 來編寫一些 Example 幫助理解。

Node

interface Node {
  type: string;
  loc: SourceLocation | null;
}

符合 Estree 規範的節點用 Node 對象進行標識,Node 對象應該符合上述接口;

  • type:節點類型,分別對應了 Javascript 中的各種語法;
  • loc:源碼的位置信息,有可能爲空(null);

SourceLocation

interface SourceLocation {
  source: string | null;
  start: Position;
  end: Position;
}
  • source:源碼片段;
  • start:開始位置;
  • end:結束位置;

Position

interface Position {
  line: number;
  column: number;
}
  • line:行信息;
  • column:列信息;


基礎類型

Expression

// extends 可理解爲“繼承”的語法糖,原文爲 <: 本文使用 extends 代替
interface Expression extends Node { }

表達式節點,數組、對象、判斷、循環皆爲表達式,在後面會更詳細的介紹。

Pattern

interface Pattern extends Node { }

模式,主要在 ES6 的解構語法中使用,類似於 Identifier。

Identifier

interface Identifier extends Expression, Pattern {
  type: "Identifier";
  name: string;
}

標識符(如變量名、函數名、屬性名),屬於表達式的一種,可以理解爲聲明一個變量/函數/... 的表達式。

  • type:類型爲 Identifier(標識符)類型;
  • name:變量名/函數名/...名;

Literal

interface Literal extends Expression {
  type: "Literal";
  value: string | boolean | null | number | RegExp;
}

字面量,指 1 和 '1' 這種字面量([] 和 {} 屬於表達式,內部實現和字面量不一樣)

  • type:類型爲 Literal(字面量);
  • value:值爲多種類型,字符串/布爾/空/數字/正則類型,都屬於字面量值類型;

RegLiteral

interface RegExpLiteral extends Literal {
  regex: {
    pattern: string;
    flags: string;
  }
}

對正則字面量更好的解析。

Statement

interface Statement extends Node { }

語句節點。

Program

interface Program extends Node {
  type: "Program";
  body: [ Statement ]
}

Program 一般是作爲根節點使用,代表了一顆完整的程序樹。

  • type:類型爲 Program
  • body:由多個語句組成的數組;

Function

interface Function extends Node {
  id: Identifier | null;
  params: [ Pattern ];
  body: BlockStatement;
}

// Example
acorn.parse('function bar(a) { }');

{
  "type": "FunctionDeclaration", // 類型爲 Function
  "id": {
    "type": "Identifier", // id 是標識符類型
    "name": "bar" // 標識符的名稱是 bar(函數名爲 bar)
  },
  "params": [
    {
      "type": "Identifier", // 參數 a 是標識符類型
      "name": "a" // 標識符的名字是 a(參數名爲 a)
    }
  ], 
  "body": {
    "type": "BlockStatement", // 函數內部是一個塊語句,當前函數內部爲空的一個塊語句
    "body": []
  }
}

函數聲明或函數表達式節點。

  • id:函數名,一般爲必填(還有匿名函數);
  • params:函數的參數集合;
  • body:塊語句(在後面會繼續提及);


Statement(語句)

ExpressionStatement

interface ExpressionStatement extends Statement {
  type: "ExpressionStatement";
  expression: Expression;
}

// Example
acorn.parse('1 + 1')

{
  "type": "ExpressionStatement", // 表達式語句
  "expression": {
    "type": "BinaryExpression", // 一元表達式(後面會提及)
    "left": {
      "type": "Literal",
      "value": 1,
      "raw": "1"
    },
    "operator": "+",
    "right": {
      "type": "Literal",
      "value": 1,
      "raw": "1"
    }
  }
}

表達式語句節點,代表的是一個表達式語句。

  • type:類型爲 ExpressionStatement
  • expression:表達式語句的內容(表達式);

BlockStatement

interface BlockStatement extends Statement {
  type: "BlockStatement";
  body: [ Statement ];
}

// Example
acorn.parse('{ 1 + 1 }')

{
  "type": "BlockStatement", // 塊語句
  "body": [
    {
      "type": "ExpressionStatement", // 塊語句包裹了我們定義的表達式語句;表達式語句只是這個塊語句中的一員,塊語句可以有多個成員;
      "expression": {
        "type": "BinaryExpression",
        "left": {
          "type": "Literal",
          "value": 1,
          "raw": "1"
        },
        "operator": "+",
        "right": {
          "type": "Literal",
          "value": 1,
          "raw": "1"
        }
      }
    }
  ]
}

塊語句,可簡單理解爲用 { } 包裹的語句。

  • type:類型爲 BlockStatement
  • body:內容爲語句組成的一個數組;

EmptyStatement

interface EmptyStatement extends Statement {
  type: "EmptyStatement";
}

// Example
acorn.parse(';')

{
  "type": "EmptyStatement" // 
}

空語句,比如一個單獨的 ; 符號;

  • type:類型爲 EmptyStatement

DebuggerStatement

interface DebuggerStatement extends Statement {
    type: "DebuggerStatement";
}

// Example
acorn.parse('debugger;')

{
  "type": "DebuggerStatement"
}

debugger 語句。

  • type:類型爲 DebuggerStatement

WithStatement

interface WithStatement extends Statement {
  type: 'WithStatement';
  object: Expression;
  body: Statement;
}

// Example
acorn.parse('with(o){ }')

{
  "type": "WithStatement",
  "object": {
    "type": "Identifier", // 使用了 o 的標識符作爲內部作用域
    "name": "o"
  },
  "body": {
    "type": "BlockStatement", // 內部語句使用一個塊語句
    "body": []
  }
}

with 語句,用於設置代碼在特定對象中的作用域。

  • type:類型爲 WithStatement
  • object:with 語句中的 () 中的內容,指定語句的作用域,可以爲一個自定義的表達式;
  • body:主體,語句類型,可以爲塊語句 with(o) { ... },也可以爲表達式語句 with(o) a + a

ReturnStatement

interface ReturnStatement extends Statement {
  type: "ReturnStatement";
  argument: Expression | null;
}

// Example
acorn.parse('function bar() { return true }')

{
  "type": "FunctionDeclaration",
  "id": {
    "type": "Identifier",
    "name": "bar"
  },
  "expression": false,
  "generator": false,
  "async": false,
  "params": [],
  "body": {
    "type": "BlockStatement",
    "body": [
      {
        "type": "ReturnStatement", // 類型
        "argument": { 
          "type": "Literal", // 返回值是字面量類型
          "value": true, // 值爲 true
          "raw": "true"
        }
      }
    ]
  }
}

返回語句,通常用於返回函數執行結果;

  • type:類型爲 ReturnStatement;
  • argument:返回的內容,是一個任意類型的表達式;

LabeledStatement

interface LabeledStatement extends Statement {
  type: "LabeledStatement";
  body: Statement;
  label: Identifier;
}

// Example
acorn.parse('labelName:while(true){ }')

{
  "type": "LabeledStatement",
  "body": { // Label 的內容
    "type": "WhileStatement",
    "test": {
      "type": "Literal",
      "value": true,
      "raw": "true"
    },
    "body": {
      "type": "BlockStatement",
      "body": []
    }
  },
  "label": {
    "type": "Identifier", // Label 名稱
    "name": "labelName"
  }
}

Label 語句,一般用於顯式標識 Statement

  • type:類型爲 LabeledStatement
  • body:主體,是 Label 對應的語句;
  • label:Label 的名稱;

BreakStatement

interface BreakStatement extends Statement {
  type: "BreakStatement";
  label: Identifier | null;
}

// Example
acorn.parse('while(true) { break; }')

{
  "type": "WhileStatement",
  "test": {
    "type": "Literal",
    "value": true,
    "raw": "true"
  },
  "body": {
    "type": "BlockStatement",
    "body": [
      {
        "type": "BreakStatement",
        "label": {} // 這個 break 沒有 label,則 break 對應的語句需要向上級查詢
      }
    ]
  }
}

break 語句,通常用來“跳出”循環;

  • type:類型爲 BreakStatement
  • label:如果需要指定“跳出”的語句,則需要指定 label 屬性爲 LabeledStatement 中的 label 屬性(Identifier);

ContinueStatement

interface ContinueStatement extends Statement { 
    type: "ContinueStatement"; 
    label: Identifier | null; 
}

continue 語句,通常用來“跳出”循環中的一個迭代;

  • type:類型爲 ContinueStatement
  • label:如果需要指定“跳出”的語句,則需要指定 label 屬性爲 LabeledStatement 中的 label 屬性(Identifier);

IfStatement

interface IfStatement extends Statement {
  type: "IfStatement";
  test: Expression;
  consequent: Statement;
  alternate: Statement | null;
}

// Example
acorn.parse('if (true) {} else if(false) a++')

// 分析一個比較經典的語法,else if
{
  "type": "IfStatement",
  "test": {
    "type": "Literal", // 判斷條件爲一個字面量
    "value": true,
    "raw": "true"
  },
  "consequent": {
    "type": "BlockStatement", // 如果判斷爲 true 則執行這個塊語句
    "body": []
  },
  "alternate": {
    "type": "IfStatement", // else 語句是一個 IfStatement 可以得出 else if () === else { if () }
    "test": {
      "type": "Literal",
      "value": false,
      "raw": "false"
    },
    "consequent": {
      "type": "ExpressionStatement",
      "expression": {
        "type": "UpdateExpression", // 最終滿足條件後執行了一個 UpdateExpression
        "operator": "++",
        "prefix": false,
        "argument": {
          "type": "Identifier",
          "name": "a"
        }
      }
    },
    "alternate": {} // 第二個 IfStatement 沒有 else 語句
  }
}

if 語句,滿足 test 條件執行 consequent 語句,不滿足條件則執行 alternate 語句。

  • type:類型爲 IfStatement;
  • test:判斷條件,也就是 if (expression) 括號中的內容;
  • consequent:條件爲 true 時執行的語句;
  • alternate:條件爲 false 時執行的語句,也可以設置爲另一個 IfStatement,就變成了 else if 語法;

SwitchStatement

interface SwitchStatement extends Statement {
  type: "SwitchStatement";
  discriminant: Expression;
  cases: [ SwitchCase ]
}

interface SwitchCase extends Node {
  type: "SwitchCase";
  test: Expression | null;
  consequent: [ Statement ];
}

// Example
acorn.parse('switch(a) { case 1: a = 2; break; }');

{
  "type": "SwitchStatement", // 類型
  "discriminant": {
    "type": "Identifier", // 主體是個標識符,條件成立則進入 cases 處理邏輯
    "name": "a"
  },
  "cases": [
    {
      "type": "SwitchCase",
      "consequent": [
        {
          "type": "ExpressionStatement", // 判斷條件成立執行第一個 ExpressionStatement
          "expression": {
            "type": "AssignmentExpression",
            "operator": "=",
            "left": {
              "type": "Identifier",
              "name": "a"
            },
            "right": {
              "type": "Literal",
              "value": 2,
              "raw": "2"
            }
          }
        },
        {
          "type": "BreakStatement", // 第二個語句爲 Break 語句
          "label": {}
        }
      ],
      "test": {
        "type": "Literal", // 判斷條件爲字面量
        "value": 1,
        "raw": "1"
      }
    }
  ]
}

Switch 語句

  • type:類型爲 SwitchStatement
  • discriminant:斷言符,是 switch(...) 括號中的內容;
  • cases:一個 SwitchCase 構成的數組;

ThrowStatement

interface ThrowStatement extends Statement { 
    type: "ThrowStatement"; 
    argument: Expression; 
}

// Example
acorn.parse('throw new Error()');

{
  "type": "ThrowStatement",
  "argument": {
    "type": "NewExpression", // new 表達式
    "callee": {
      "type": "Identifier",
      "name": "Error"
    },
    "arguments": []
  }
}

throw 語句,一般用於拋出錯誤;

  • type:類型爲 ThrowStatement
  • argument:throw 後面的表達式,需要拋出的內容;

TryStatement

interface TryStatement extends Statement {
  type: "TryStatement";
  block: BlockStatement;
  handler: CatchClause | null;
  finalizer: BlockStatement | null;
}

interface CatchClause extends Node { 
    type: "CatchClause"; 
    param: Pattern; 
    body: BlockStatement; 
}  

// Example
acorn.parse('try { throw new Error() } catch (error) {  } finally {  } ');

{
  "type": "TryStatement",
  "block": { // try 的塊語句
    "type": "BlockStatement",
    "body": [
      {
        "type": "ThrowStatement",
        "argument": {
          "type": "NewExpression",
          "callee": {
            "type": "Identifier",
            "name": "Error"
          },
          "arguments": []
        }
      }
    ]
  },
  "handler": {
    "type": "CatchClause", // catch 語句
    "param": {
      "type": "Identifier", 
      "name": "error" // catch 語句參數的標識符名爲 error
    },
    "body": {
      "type": "BlockStatement", // catch 語句的主體
      "body": []
    }
  },
  "finalizer": { // finally 語句
    "type": "BlockStatement", // finally 語句的主體
    "body": []
  }
}

TryStatement 爲 try() { ... } catch(param) { ... } 語句;

  • type:類型爲 TryStatement
  • block:try 語句的主體,是一個塊語句;
  • handler:catch 語句的主體,包含一個參數;
  • finalizer:finally 語句主體;

WhileStatement

interface WhileStatement extends Statement {
  type: "WhileStatement";
  test: Expression;
  body: BlockStatement;
}

// Example
acorn.parse('while(expression) {}');

{
  "type": "WhileStatement",
  "test": {
    "type": "Identifier",
    "name": "expression"
  },
  "body": {
    "type": "BlockStatement",
    "body": []
  }
}

while 語句,通常用於條件循環。(還有與該節點類似的 DoWhileStatement

  • type:類型爲 WhileStatement
  • test:while(expression) {} 中的 expression,條件滿足時將進入循環主體;
  • body:循環主體,爲 BlockStatement

ForStatement

interface ForStatement extends Statement {
  type: "ForStatement";
  init: VariableDeclaration | Expression | null;
  test: Expression | null;
  update: Expression | null;
  body: BlockStatement;
}

// Example
acorn.parse('for (let i = 0; i <= 10; i++) { }');

{
  "type": "ForStatement",
  "init": {
    "type": "VariableDeclaration", // 初始值是一個 VariableDeclaration (變量聲明)
    "declarations": [
      {
        "type": "VariableDeclarator",
        "id": {
          "type": "Identifier", // 變量名爲 i
          "name": "i"
        },
        "init": {
          "type": "Literal", // 初始值爲 0
          "value": 0,
          "raw": "0"
        }
      }
    ],
    "kind": "let"
  },
  "test": {
    "type": "BinaryExpression", // 判斷條件爲一個表達式
    "left": {
      "type": "Identifier", // 表達式左邊是 變量 i
      "name": "i"
    },
    "operator": "<=", // 操作符是 <=
    "right": {
      "type": "Literal", // 表達式右邊是 字面量是 10
      "value": 10,
      "raw": "10"
    }
  },
  "update": {
    "type": "UpdateExpression", // 更新語句是一個 UpdateExpression
    "operator": "++",
    "prefix": false,
    "argument": {
      "type": "Identifier",
      "name": "i"
    }
  },
  "body": {
    "type": "BlockStatement", // 循環主體
    "body": []
  }
}

ForStatement 表示的是最常用的 for (init; test; update;) { ... } 循環;

  • type:類型爲 ForStatement
  • init:循環中的初始值;
  • test:循環的判斷條件,一般結合 init 中定義的變量進行判斷;
  • update:每次循環結束後的更新函數,一般用於更新 test 中使用到的變量;
  • body:循環主體;

ForInStatement

interface ForInStatement extends Statement {
  type: "ForInStatement";
  left: VariableDeclaration | Pattern;
  right: Expression;
  body: Statement;
}

// Example
{
  "type": "ForInStatement",
  "left": {
    "type": "VariableDeclaration", // 變量聲明
    "declarations": [
      {
        "type": "VariableDeclarator",
        "id": {
          "type": "Identifier",
          "name": "key" // 變量名爲 key
        },
        "init": {}
      }
    ],
    "kind": "let" // 聲明類型爲 let
  },
  "right": {
    "type": "Identifier", // 右邊是一個標識符
    "name": "obj"
  },
  "body": {
    "type": "BlockStatement",
    "body": []
  }
}

for in 循環,一般用於遍歷一個對象。

  • type:類型爲 ForStatement
  • left:左邊一般是一個變量聲明,也可以是一個解構函數,比如 for(let { a, b } in obj) { }
  • right:右邊是一個表達式,一般爲變量標識符,一個對象;

Declaration

interface Declaration extends Statement { }

聲明語句節點。

FunctionDeclaration

interface FunctionDeclaration extends Function, Declaration {
  type: "FunctionDeclaration";
  id: Identifier;
}

// Example
acorn.parse('function run() {  }');

{
  "type": "FunctionDeclaration", // 函數聲明語句
  "id": {
    "type": "Identifier",
    "name": "run" // 標識符爲 run
  },
  "params": [], // 參數爲空
  "body": {
    "type": "BlockStatement", // 函數主體
    "body": []
  }
}
  • type:類型爲 FunctionDeclaration
  • id:函數名,不能爲空;

VariableDeclaration

interface VariableDeclaration extends Declaration {
  type: "VariableDeclaration";
  declarations: [ VariableDeclarator ];
  kind: "var" | "const" | "let";
}

interface VariableDeclarator <: Node { 
    type: "VariableDeclarator"; 
    id: Pattern; 
    init: Expression | null; 
}

// Example
{
  "type": "VariableDeclaration",
  "declarations": [
    {
      "type": "VariableDeclarator",
      "id": {
        "type": "Identifier",
        "name": "a" // 變量名爲 a
      },
      "init": {
        "type": "Literal",
        "value": 1,
        "raw": "1" // 變量值爲 1
      }
    },
    {
      "type": "VariableDeclarator",
      "id": {
        "type": "Identifier",
        "name": "b" // 變量名爲 b
      },
      "init": {
        "type": "Literal",
        "value": 2,
        "raw": "2" // 變量值爲 2
      }
    }
  ],
  "kind": "const" // 聲明類型爲 const
}

變量聲明語句。

  • type:類型爲 VariableDeclaration
  • declarations:變量聲明數組,可以同時聲明多個變量;
  • kind:聲明類型,可以是 var | let | const 中的一種;

Expression

interface Expression extends Node { }

表達式節點。

ThisExpression

interface ThisExpression extends Expression {
  type: "ThisExpression";
}

// Example
acorn.parse('this');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "ThisExpression"
  }
}

表示 this。

ArrayExpression

interface ArrayExpression extends Expression {
  type: "ArrayExpression";
  elements: [ Expression | null ];
}

// Example
acorn.parse('[1, a, 1 === 1]');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "ArrayExpression",
    "elements": [
      {
        "type": "Literal", // 第一個元素是字面量
        "value": 1,
        "raw": "1"
      },
      {
        "type": "Identifier", // 第二個元素是變量標識符
        "name": "a"
      },
      {
        "type": "BinaryExpression", // 第三個元素是表達式
        "left": {
          "type": "Literal",
          "value": 1,
          "raw": "1"
        },
        "operator": "===",
        "right": {
          "type": "Literal",
          "value": 1,
          "raw": "1"
        }
      }
    ]
  }
}

數組表達式,一般用於直接創建一個數組。

  • type: 類型爲 ArrayExpression
  • elements:數組元素集合,元素爲表達式類型;

ObjectExpression

interface ObjectExpression extends Expression {
  type: "ObjectExpression";
  properties: [ Property ];
}

interface Property extends Node {
  type: "Property";
  key:  Literal | Identifier;
  value: Expression;
  kind: "init" | "get" | "set";
}

interface FunctionExpression <: Function, Expression { 
    type: "FunctionExpression"; 
}
// Example
acorn.parse('const obj = {a: 1, 2: b, get c() { }}');

{
  "type": "VariableDeclaration", // 聲明語句
  "declarations": [
    {
      "type": "VariableDeclarator",
      "id": {
        "type": "Identifier",
        "name": "obj" // 變量名爲 obj
      },
      "init": {
        "type": "ObjectExpression", // 值爲對象表達式
        "properties": [
          {
            "type": "Property",
            "method": false,
            "shorthand": false,
            "computed": false,
            "key": {
              "type": "Identifier",
              "name": "a" // key 值爲 a
            },
            "value": {
              "type": "Literal",
              "value": 1, // 值爲 1
              "raw": "1"
            },
            "kind": "init" // 類型爲初始化
          },
          {
            "type": "Property",
            "method": false,
            "shorthand": false,
            "computed": false,
            "key": {
              "type": "Literal",
              "value": 2, // key 爲 字面量 2
              "raw": "2"
            },
            "value": {
              "type": "Identifier",
              "name": "b" // 值爲變量標識符 b
            },
            "kind": "init" // 類型爲初始化
          },
          {
            "type": "Property",
            "method": false,
            "shorthand": false,
            "computed": false,
            "key": {
              "type": "Identifier", // key 爲變量標識符 c
              "name": "c"
            },
            "kind": "get", // 類型爲 getter
            "value": {
              "type": "FunctionExpression", // 值是一個函數表達式
              "id": {},
              "expression": false,
              "generator": false,
              "async": false,
              "params": [],
              "body": {
                "type": "BlockStatement", // 函數主體
                "body": []
              }
            }
          }
        ]
      }
    }
  ],
  "kind": "const"
}

對象表達式,一般用於創建對象。

  • type:類型爲 ObjectExpression
  • properties:鍵值對(對象屬性)集合;

UnaryExpression

interface UnaryExpression extends Expression {
  type: "UnaryExpression";
  operator: UnaryOperator;
  prefix: boolean;
  argument: Expression;
}

enum UnaryOperator { 
    "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" 
}

// Example
acorn.parse('+a');

{
  "type": "ExpressionStatement", // 類型爲表達式語句
  "expression": {
    "type": "UnaryExpression", // 一元表達式
    "operator": "+", // 運算符爲 + 
    "prefix": true, // 爲前置表達式
    "argument": {
      "type": "Identifier", // 操作的表達式爲標識符 a
      "name": "a"
    }
  }
}

一元運算表達式節點。

  • type:類型爲 UnaryExpression
  • operator:運算符;
  • prefix:是否爲前綴運算符;
  • argument:執行運算的表達式,如變量標識符;

UpdateExpression

interface UpdateExpression extends Expression { 
    type: "UpdateExpression"; 
    operator: UpdateOperator; 
    argument: Expression; 
    prefix: boolean; 
}  

enum UpdateOperator { 
  "++" | "--" 
}

// Example
acorn.parse('a++');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "UpdateExpression",
    "operator": "++",
    "prefix": false,
    "argument": {
      "type": "Identifier",
      "name": "a"
    }
  }
}

更新運算符,只有 ++--

  • type:類型爲 UnaryExpression
  • operator:運算符,只有 ++--
  • prefix:是否爲前綴運算符;
  • argument:執行運算的表達式,如變量標識符;

BinaryExpression

interface BinaryExpression extends Expression {
  type: "BinaryExpression";
  operator: BinaryOperator;
  left: Expression;
  right: Expression;
}

enum BinaryOperator { 
    "==" | "!=" | "===" | "!==" 
         | "<" | "<=" | ">" | ">=" 
         | "<<" | ">>" | ">>>" 
         | "+" | "-" | "*" | "/" | "%" 
         | "|" | "^" | "&" | "in" 
         | "instanceof" 
}

// Example
acorn.parse('a + b');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "BinaryExpression",
    "left": {
      "type": "Identifier", // 左側表達式爲標識符 a
      "name": "a"
    },
    "operator": "+", // 運算符爲 +
    "right": {
      "type": "Identifier", // 右側表達式爲標識符 b
      "name": "b"
    }
  }
}

二元運算表達式。

  • type:類型爲 BinaryExpression
  • operator:運算符;
  • left:左側表達式,該表達式也可能是一個 BinaryExpression
  • right:右側表達式,通常爲一個變量標識符;

AssignmentExpression

interface AssignmentExpression extends Expression {
  type: "AssignmentExpression"; 
  operator: AssignmentOperator; 
  left: Pattern | Expression; 
  right: Expression; 
}

enum AssignmentOperator { 
    "=" | "+=" | "-=" | "*=" | "/=" | "%=" 
        | "<<=" | ">>=" | ">>>=" 
        | "|=" | "^=" | "&=" 
}

// Example
acorn.parse('a += 1');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "AssignmentExpression",
    "operator": "+=", // 運算符,我們常把 a += 1 理解爲 a = a + 1,其實他們在解構後是不同的結構,前者是 AssignmentExpression,後者是 AssignmentExpression + BinaryExpression
    "left": {
      "type": "Identifier", // 左側爲標識符 a
      "name": "a"
    },
    "right": {
      "type": "Literal", // 右側爲字面量 1
      "value": 1,
      "raw": "1"
    }
  }
}

賦值表達式。

  • type:類型爲 ExpressionStatement
  • operator:運算符;
  • left:左側,通常爲一個變量標識符;
  • right:右側,通常爲一個字面量或變量標識符;

LogicalExpression

interface LogicalExpression extends Expression { 
    type: "LogicalExpression"; 
    operator: LogicalOperator; 
    left: Expression; 
    right: Expression; 
}  

enum LogicalOperator { 
    "||" | "&&" 
}

// Example
acorn.parse('a || b');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "LogicalExpression",
    "left": {
      "type": "Identifier", // 左側爲標識符 a
      "name": "a"
    },
    "operator": "||", // 運算符爲 ||
    "right": {
      "type": "Identifier", // 右側爲標識符 b
      "name": "b"
    }
  }
}

邏輯表達式/與或表達式;

  • type:類型爲 LogicalExpression
  • operator:運算符,爲 ||&&
  • left:左側表達式;
  • right:右側表達式;

ConditionalExpression

interface ConditionalExpression extends Expression {
  type: "ConditionalExpression"; 
  test: Expression; 
  alternate: Expression; 
  consequent: Expression; 
}

// Example
acorn.parse('a ? 1 : 0');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "ConditionalExpression",
    "test": {
      "type": "Identifier", // 判斷條件爲 a
      "name": "a"
    },
    "consequent": {
      "type": "Literal", // 條件成立返回字面量 1
      "value": 1,
      "raw": "1"
    },
    "alternate": {
      "type": "Literal", // 條件不成立返回字面量 2
      "value": 0,
      "raw": "0"
    }
  }
}

三元表達式,即 boolean ? true : false

  • type:類型爲 ConditionalExpression;
  • test:判斷條件;
  • consequent:判斷條件爲 true 時執行的語句;
  • alternate:判斷條件爲 false 時執行的語句;

MemberExpression

interface MemberExpression extends Expression {
  type: "MemberExpression"; 
  object: Expression; 
  property: Expression; 
  computed: boolean; 
}

// Example
acorn.parse('obj.b');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "MemberExpression", // 成員表達式
    "object": {
      "type": "Identifier", // 對象爲標識符 obj
      "name": "obj"
    },
    "property": {
      "type": "Identifier", // 屬性爲標識符 b
      "name": "b"
    },
    "computed": false // 使用 . 來引用對象
  }
}

成員表達式,通常用於在對象中取某屬性的值;

  • type:類型爲 MemberExpression
  • object:取值的對象,一般爲變量標識符;
  • property:需要獲取的對象屬性,一般爲變量標識符;
  • computed:兩種取值方式,該值爲 false 則是 obj.a 形式取值,該值爲 true 時則爲 obj[a] 形式取值;

CallExpression

interface CallExpression extends Expression {
  type: "CallExpression"; 
  callee: Expression; 
  arguments: [ Expression ]; 
}

// Example
acorn.parse('fun(a)');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "CallExpression", // 函數調用表達式
    "callee": {
      "type": "Identifier", // callee 爲一個標識符 fun
      "name": "fun"
    },
    "arguments": [
      {
        "type": "Identifier", // 參數爲標識符 a
        "name": "a"
      }
    ]
  }
}

函數調用表達式,通常用於調用函數;

  • type:類型爲 CallExpression
  • callee:調用的函數本身,一般爲標識符,指向一個函數;
  • arguments:參數列表,爲表達式的集合;

SequenceExpression

interface SequenceExpression extends Expression { 
  type: "SequenceExpression"; 
  expressions: [ Expression ]; 
}  

// Example
acorn.parse('a, b');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "SequenceExpression",
    "expressions": [
      {
        "type": "Identifier",
        "name": "a"
      },
      {
        "type": "Identifier",
        "name": "b"
      }
    ]
  }
}

逗號分隔符表達式;

  • type:類型爲 ExpressionStatement
  • expressions:表達式集合;

NewExpression

interface NewExpression extends CallExpression { 
  type: "NewExpression"; 
}  

// Example
acorn.parse('new Car()');

{
  "type": "ExpressionStatement",
  "expression": {
    "type": "NewExpression", 
    "callee": {
      "type": "Identifier",
      "name": "Car"
    },
    "arguments": []
  }
}

new 表達式,繼承於 CallExpression

  • type:類型爲 NewExpression

結語

其實 AST 語法樹的語法遠不止上述這些,隨着新語法的推出,還有很多新的語法,具體的大家可以在 MDN 文檔 中進行查閱,感謝您的閱讀!

原文地址,歡迎 Star

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章