Больше сообщений в блоге, добро пожаловать в StarGithub/Blog
Дерево абстрактного синтаксиса JS Подробное объяснение см. в сопутствующей статье:Дерево абстрактного синтаксиса Javascript для продвинутого внешнего интерфейса
Javascript-кодРазобратьШаг (Parse) делится на две фазы:Лексический анализа такжеСинтаксический анализ. Этот шаг получает код и выводитабстрактное синтаксическое дерево, также известный как АСТ.
По мере того, как экология Babel становится все более и более полной, мы обычно используем Babel для анализа процесса разбора кода. Вавилон используетESTreeи модифицированный AST, документацию по его ядру можно найти [здесь](https://github.com/babel/babel/blob/master/doc/ast/spec.md).
В процессе анализа AST Javascript с помощью инструментовAST ExplorerЭто может помочь нам лучше понять восприятие узлов AST.
Чтобы помочь вам лучше совместить анализ примеров и понять состав основных типов узлов Babylon AST, здесь перечислены 13 распространенных примеров, а также соответствующие узлы AST и подробный анализ типов узлов соответственно.
AST всего следующего кода основан наBabylon7
объявление переменной
код
let a = 'hello'
AST
VariableDeclaration
объявление переменной,kind
Какой тип объявления представляет свойство с момента введения ES6const/let
.declarations
Представляет несколько описаний объявления, поскольку мы можем:let a = 1, b = 2;
.
interface VariableDeclaration <: Declaration {
type: "VariableDeclaration";
declarations: [ VariableDeclarator ];
kind: "var";
}
VariableDeclarator
описание объявления переменной,id
представляет узел имени переменной,init
Выражение, представляющее начальное значение, которое может бытьnull
.
interface VariableDeclarator <: Node {
type: "VariableDeclarator";
id: Pattern;
init: Expression | null;
}
Identifier
Идентификаторы, как я думаю, должны называться — это имена, которые мы настраиваем при написании JS, такие как имена переменных, имена функций и имена атрибутов, которые классифицируются как идентификаторы. Соответствующий интерфейс выглядит следующим образом:
interface Identifier <: Expression, Pattern {
type: "Identifier";
name: string;
}
Идентификатор может быть выражением или шаблоном деструктурирования (синтаксис деструктурирования в ES6). мы увидим позжеExpression
а такжеPattern
связанный контент.
Literal
Буквально, не имелось в виду здесь[]
или{}
Эти, но литералы, которые семантически представляют значение, такие как1
,“hello”
, true
эти и регулярные выражения (есть расширенныйNode
для представления регулярных выражений), например/\d?/
. Давайте посмотрим на определение документа:
interface Literal <: Expression {
type: "Literal";
value: string | boolean | null | number | RegExp;
}
value
Это соответствует значению литерала, мы можем видеть тип литерального значения, строка, логическое значение, значение,null
и регулярный.
двоичные арифметические выражения
код
let a = 3+4
AST
BinaryExpression
Узел выражения бинарного оператора,left
а такжеright
представляет два выражения слева и справа от оператора,operator
Представляет бинарный оператор.
interface BinaryExpression <: Expression {
type: "BinaryExpression";
operator: BinaryOperator;
left: Expression;
right: Expression;
}
BinaryOperator
Бинарный оператор, все значения следующие:
enum BinaryOperator {
"==" | "!=" | "===" | "!=="
| "<" | "<=" | ">" | ">="
| "<<" | ">>" | ">>>"
| "+" | "-" | "*" | "/" | "%"
| "|" | "^" | "&" | "in"
| "instanceof"
}
выражение присваивания
код
Этот пример будет немного сложнее и будет включать больше типов узлов.
this.state = {date: new Date()};
AST
ExpressionStatement
узел оператора выражения,a = a + 1
илиa++
там будетexpression
Свойство указывает на объект узла выражения (выражения будут упомянуты позже).
interface ExpressionStatement <: Statement {
type: "ExpressionStatement";
expression: Expression;
}
AssignmentExpression
узел выражения присваивания,operator
свойство представляет оператор присваивания,left
а такжеright
это выражение вокруг оператора присваивания.
interface AssignmentExpression <: Expression {
type: "AssignmentExpression";
operator: AssignmentOperator;
left: Pattern | Expression;
right: Expression;
}
AssignmentOperator
Оператор присваивания, все значения следующие: (не так много часто используемых)
enum AssignmentOperator {
"=" | "+=" | "-=" | "*=" | "/=" | "%="
| "<<=" | ">>=" | ">>>="
| "|=" | "^=" | "&="
}
MemberExpression
Узел выражения члена, то есть оператор, который ссылается на член объекта,object
узел выражения, ссылающийся на объект,property
имя атрибута,computed
еслиfalse
, что значит.
обращаться к членам,property
должно бытьIdentifier
узел, еслиcomputed
собственностьtrue
, тогда[]
цитировать, т.property
ЯвляетсяExpression
Узел, имя которого является результирующим значением выражения.
interface MemberExpression <: Expression, Pattern {
type: "MemberExpression";
object: Expression;
property: Expression;
computed: boolean;
}
ThisExpression
выражатьthis
.
interface ThisExpression <: Expression {
type: "ThisExpression";
}
ObjectExpression
узел выражения объекта,property
Свойство — это массив, который представляет каждую пару ключ-значение объекта, а каждый элемент — это узел свойства.
interface ObjectExpression <: Expression {
type: "ObjectExpression";
properties: [ Property ];
}
Property
Узлы свойств в выражениях объектов.key
представляет ключ,value
представляет собой значение, поскольку синтаксис ES5 имеетget/set
существует, значит, естьkind
Атрибут, используемый для обозначения нормальной инициализации илиget/set
.
interface Property <: Node {
type: "Property";
key: Literal | Identifier;
value: Expression;
kind: "init" | "get" | "set";
}
NewExpression
new
выражение.
interface NewExpression <: CallExpression {
type: "NewExpression";
}
выражение вызова функции
код
console.log(`Hello ${name}`)
AST
CallExpression
выражение вызова функции, что означаетfunc(1, 2)
заявления этого типа.callee
Свойство — это узел выражения, представляющий функцию,arguments
представляет собой массив, элементами которого являются узлы выражений, представляющие список аргументов функции.
interface CallExpression <: Expression {
type: "CallExpression";
callee: Expression;
arguments: [ Expression ];
}
TemplateLiteral
interface TemplateLiteral <: Expression {
type: "TemplateLiteral";
quasis: [ TemplateElement ];
expressions: [ Expression ];
}
TemplateElement
interface TemplateElement <: Node {
type: "TemplateElement";
tail: boolean;
value: {
cooked: string | null;
raw: string;
};
}
стрелочная функция
код
i => i++
AST
ArrowFunctionExpression
Выражения стрелочных функций.
interface ArrowFunctionExpression <: Function, Expression {
type: "ArrowFunctionExpression";
body: BlockStatement | Expression;
expression: boolean;
}
UpdateExpression
узел выражения оператора обновления, т.е.++/--
, который похож на унарный оператор, за исключениемoperator
Тип объекта узла, на который указывает другой, здесь оператор обновления.
interface UpdateExpression <: Expression {
type: "UpdateExpression";
operator: UpdateOperator;
argument: Expression;
prefix: boolean;
}
UpdateOperator
оператор обновления, значение равно++
или--
, с узлом выражения обновленияprefix
свойство указывать до и после.
enum UpdateOperator {
"++" | "--"
}
объявление функции
код
function Hello(name = 'Lily'){
}
AST
FunctionDeclaration
Объявления функций, в отличие от ранее упомянутой функции,id
не может бытьnull
.
interface FunctionDeclaration <: Function, Declaration {
type: "FunctionDeclaration";
id: Identifier;
}
AssignmentPattern
interface AssignmentPattern <: Pattern {
type: "AssignmentPattern";
left: Pattern;
right: Expression;
}
BlockStatement
Узел оператора блока, например:if (...) { // 这里是块语句的内容 }
, блок может содержать несколько других операторов, поэтомуbody
Свойство, представляющее собой массив, представляет несколько операторов в блоке.
interface BlockStatement <: Statement {
type: "BlockStatement";
body: [ Statement ];
}
объявление класса
код
class Clock extends Component{
render(){
}
}
AST
Classes
interface Class <: Node {
id: Identifier | null;
superClass: Expression | null;
body: ClassBody;
decorators: [ Decorator ];
}
ClassBody
interface ClassBody <: Node {
type: "ClassBody";
body: [ ClassMethod | ClassPrivateMethod | ClassProperty | ClassPrivateProperty ];
}
ClassMethod
interface ClassMethod <: Function {
type: "ClassMethod";
key: Expression;
kind: "constructor" | "method" | "get" | "set";
computed: boolean;
static: boolean;
decorators: [ Decorator ];
}
если оператор
код
if(a === 0){
}
AST
IfStatement
if
Узлы операторов, очень распространенные, будут иметь три атрибута:test
представление атрибутаif (...)
выражения в скобках.
consequent
атрибутом является то, что условиеtrue
Когда оператор выполнения, как правило, оператор блока.
alternate
атрибуты используются для представленияelse
Последующий узел оператора обычно представляет собой блочный оператор, но может быть и другим.if
Узлы операторов, то есть структуры, подобные этой:if (a) { //... } else if (b) { // ... }
.alternate
Конечно, это также может бытьnull
.
interface IfStatement <: Statement {
type: "IfStatement";
test: Expression;
consequent: Statement;
alternate: Statement | null;
}
оператор переключения
код
switch(num){
case 0:
x = 'Sunday'
break;
default:
x = 'Weekday'
}
AST
SwitchStatement
switch
Узел оператора имеет два свойства:discriminant
представление атрибутаswitch
Выражение, следующее за оператором, обычно переменная,cases
собственность - этоcase
массив узлов, представляющих каждыйcase
утверждение.
interface SwitchStatement <: Statement {
type: "SwitchStatement";
discriminant: Expression;
cases: [ SwitchCase ];
}
SwitchCase
switch
изcase
узел.test
атрибут представляет этоcase
Выражение суждения ,consequent
этоcase
заявление об исполнении.
когдаtest
собственностьnull
, это значитdefault
этоcase
узел.
interface SwitchCase <: Node {
type: "SwitchCase";
test: Expression | null;
consequent: [ Statement ];
}
для заявления
код
for (var i = 0; i < 9; i++) {
}
AST
ForStatement
for
узел оператора цикла, атрибутinit/test/update
соответственно указаноfor
Три выражения в скобках оператора, значение инициализации, условие оценки цикла и оператор обновления переменной, выполняемый в каждом цикле (init
Может быть объявлением переменной или выражением). Все три свойства могут бытьnull
,Прямо сейчасfor(;;){}
.body
Атрибут используется для представления оператора, который должен выполняться в цикле.
interface ForStatement <: Statement {
type: "ForStatement";
init: VariableDeclaration | Expression | null;
test: Expression | null;
update: Expression | null;
body: Statement;
}
импорт модуля
код
import React from 'react'
AST
ImportDeclaration
объявление модуля.
interface ImportDeclaration <: ModuleDeclaration {
type: "ImportDeclaration";
specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
source: Literal;
}
ImportDefaultSpecifier
interface ImportDefaultSpecifier <: ModuleSpecifier {
type: "ImportDefaultSpecifier";
}
экспорт модуля
код
export default Clock
AST
ExportDefaultDeclaration
interface OptFunctionDeclaration <: FunctionDeclaration {
id: Identifier | null;
}
interface OptClasDeclaration <: ClassDeclaration {
id: Identifier | null;
}
interface ExportDefaultDeclaration <: ModuleDeclaration {
type: "ExportDefaultDeclaration";
declaration: OptFunctionDeclaration | OptClassDeclaration | Expression;
}
Метод рендеринга JSX
Код:
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}