热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScriptAST抽象语法树常见节点及结构

文章目录前言Program(程序)Identifier(标识符)Literal(字面量)Vari

文章目录

  • 前言
  • Program(程序)
  • Identifier(标识符)
  • Literal(字面量)
  • VariableDeclarator(变量声明符)
  • Property(属性)
  • Declaration(声明)
    • VariableDeclaration-变量声明
    • FunctionDeclaration-函数声明
  • Statement(语句)
    • BlockStatement-块语句
    • ExpressionStatement-表达式语句
    • IFStatement-如果语句
    • WhileStatement-While循环语句
    • ForStatement-For循环语句
    • ReturnSatement-返回语句
  • Expression(表达式)
    • AssignmentExpression-赋值表达式
    • FunctionExpression-函数表达式
    • BinaryExpression-二元表达式
    • MemberExpression-成员表达式
    • CallExpression-调用表达式
    • ObjectExpression-对象表达式
    • ArrayExpression-数组表达式
    • UpdateExpression-更新运算表达式
    • SequenceExpression-序列表达式
  • 参考文章


前言

最近开始接触AST,用于解决JS代码混淆的问题。

在看@渔哥的文章,虽然目前还是有点云里雾里的。

本文总结了JS抽象语法树中常见节点及结构。

推荐使用下方网站,结合例子对照观察。

工具网站:https://astexplorer.net/



Program(程序)

结构:

{"type": "Program","body": [], // 多个节点"sourceType": "module","range": [] //代码起始位置
}

Identifier(标识符)

可以简单的理解为变量名,函数名,属性名

{"type": "Identifier","name": "", //"range": [] // 代码起始位置
}

例子:

a
_$0x

Literal(字面量)

可以理解为一个具体的值

结构:

{"type": "Literal","value": 1, // 真实值"raw": "1", // 字符串形式的值"range": []
}

例子:

1
'2'
0x10

VariableDeclarator(变量声明符)

属于declarations中的一个元素

var a = 1, b = 2;

其中 a = 1 b = 2属于两个变量声明符

结构:

{"type": "VariableDeclarator","id": Identifier, // 变量名"init": null, // 初始化,如果声明并赋值,此处就有值,只声明未赋值则为null"range": []
}

例子:

var a, b = 2;

Property(属性)

属于properties的元素

键值对

由于 ES5 语法中有 get/set 的存在,所以有一个 kind 属性,用来表示是普通的初始化,或者是 get/set

结构:

{"type": "Property","key": "", // 键"computed": "","value": "", // 值"kind": "init","method": false,"shorthand": false,"range": []
}

Declaration(声明)

VariableDeclaration-变量声明


声明变量

结构:

{'type': "VariableDeclaration",'declarations': [VariableDeclarator, VariableDeclarator...], // `具体的声明, 这是一个列表,因为可以一次性声明多个变量`'kind': "变量修饰符,例如,var、let、const",'range': []// 声明代码的起始位置
}

例子:

var a;
var c, b;

FunctionDeclaration-函数声明


函数的声明

结构:

{'type': 'FunctionDeclaration','id': '', // 可以简单的理解为函数名'params': [], // 参数'body': BlockSatement // 函数的主体内容,多为块语句'generator': false,'expression': false,'async': false,'range': []
}

例子:

function func(a, b) {}

Statement(语句)

BlockStatement-块语句


代码块,简单点理解就是{}包起来的代码

结构:

{"type": "BlockStatement","body": [], // 代码主体"range": []
}

例子:

function a () {}
{}

ExpressionStatement-表达式语句

结构:

{"type": "ExpressionStatement","expression": // 表达式, 例如赋值表达式"range": []
}

IFStatement-如果语句


if 语句

if (a === 1) {}

结构:

{'type': 'IFStatement','test': '', // 判断,if语句()中的内容'consequent': '', // 结果,就是满足这个条件后,后续要执行的代码块'alternate': '', // else 中的内容,如果没有else,则为null'range':
}

举例:

if (a === 1) {console.log(1);
} else {console.log(2);
}

WhileStatement-While循环语句

结构:

{"type": "WhileStatement","test": ,//"body": BlockStatement// 循环体内的代码块"range": []
}

例子:

while (1) {}

ForStatement-For循环语句

结构:

{"type": "ForStatement","init": // 初始化, 多为变量的声明"test": BinaryExpression // 判断"update": UpdateExpression // 更新表达式"range": []
}

例子:

for (var i &#61; 0; i < p.length; i&#43;&#43;) {
}

ReturnSatement-返回语句

结构&#xff1a;

{"type": "RetuenStatement","argument": // 返回的值, 可以是具体的值&#xff0c;也可以是一个表达式"range": []
}

例子&#xff1a;

function func() {return 1;
}

Expression&#xff08;表达式&#xff09;

如果要执行一个表达式&#xff0c;必定由 语句 携带着。


AssignmentExpression-赋值表达式


给变量赋值

结构&#xff1a;

{"type": "AssignmentExpression","operator": "&#61;","left": Identifier, // 操作符左边, 多为Identifier"right": // 操作符右边, 可能为&#xff0c;Identifier&#xff0c;Literal&#xff0c; FucntionExpression"range": [] // 代码起始位置
}

例子&#xff1a;

a &#61; 1;
a &#43;&#61; 1;
a |&#61; 1;
a ^&#61; 2;

FunctionExpression-函数表达式


{"type": "FunctionExpression""id": null"params": [Identifier, ] // 函数的参数"body": BlockStatement// 函数体&#xff0c; 就是大括号里面的代码 "generator": false,"expression": false,"async": false,"range": []
}

BinaryExpression-二元表达式


结构&#xff1a;

{&#39;type&#39;: &#39;BinaryExpression&#39;,&#39;operator&#39;: &#39;&#61;&#61;&#61;&#39; // 二元操作符&#xff0c;比较操作符&#xff0c; <, > , &#61;&#61;&#61;&#xff0c;&#43;&#xff0c;- ...&#39;left&#39;: &#39;&#39; // 操作符的左边&#39;right&#39;: &#39;&#39; // 操作符的右边
}

MemberExpression-成员表达式


简言之&#xff0c;就是访问对象的某个属性&#xff0c;这个属性就是成员

结构&#xff1a;

{&#39;type&#39;: &#39;MemberExpression&#39;,&#39;computed&#39;: true&#xff0c; // 计算, a[&#39;a&#39;]为true&#xff0c; a.a为false&#39;object&#39;: &#39;&#39;, // 对象&#39;property&#39;: &#39;&#39;&#xff0c; // 成员名&#39;range&#39;: // 代码起始位置
}

例子&#xff1a;

a.a
a[&#39;a&#39;]

两者对比

image-20210606110152169

CallExpression-调用表达式


用于函数的调用&#xff0c;

结构&#xff1a;

{&#39;type&#39;: &#39;CallExpression&#39;,&#39;callee&#39;: &#39;&#39;, // 被调用者&#xff0c;可以理解为被调用的方法&#39;arguments&#39;: [], // 传递的参数&#39;range&#39;: []
}

举例&#xff1a;

console.log(1);

此时的callee&#xff0c;就是console.log&#xff0c;则类型为MemberExpression

atob(&#39;a&#39;)

此时的calledd&#xff0c;就是atob&#xff0c;则类型为Identifier

ObjectExpression-对象表达式


结构&#xff1a;

{"type": "ObjectExpression","properties": [Property, Property], // 属性"range": []
}

ArrayExpression-数组表达式

结构&#xff1a;

{"type": "ArrayExpression","elements": [], // 元素"range": []
}

例子&#xff1a;

a &#61; [1, 2]

UpdateExpression-更新运算表达式


update 运算表达式节点&#xff0c;即 &#43;&#43;/--&#xff0c;和一元运算符类似&#xff0c;只是 operator 指向的节点对象类型不同&#xff0c;这里是 update 运算符。

结构&#xff1a;

{"type": "UpdateExpression","operator": "&#43;&#43;", // 或者--"argument": ,"prefix": false, // 运算符&#xff0c;是否在前面&#xff0c;&#43;&#43;i则为true&#xff0c; i&#43;&#43;为false"range": []
}

例子&#xff1a;

i&#43;&#43;
&#43;&#43;i

SequenceExpression-序列表达式

结构&#xff1a;

{"type": "SequenceExpression","expressions": [], // 包含的序列节点"range": []
}

例子&#xff1a;

function func () {var a &#61; 1;return a &#61; 2, 2
}

a &#61; 2, 2就是序列表达式

参考文章

[1] 13 个示例快速入门 JS 抽象语法树


推荐阅读
author-avatar
无极圈颜汐
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有