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 文檔 中進行查閱,感謝您的閱讀!