function add(a, b) {
return a + b
首先,我们拿到的这个语法块,是一个FunctionDeclaration(函数定义)对象。
用力拆开,它成了三块:
-
一个id,就是它的名字,即add
-
两个params,就是它的参数,即[a, b]
-
一块body,也就是大括号内的一堆东西
add没办法继续拆下去了,它是一个最基础Identifier(标志)对象,用来作为函数的唯一标志,就像人的姓名一样。
name: 'add'
type: 'identifier'
params继续拆下去,其实是两个Identifier组成的数组。之后也没办法拆下去了。
name: 'a'
type: 'identifier'
name: 'b'
type: 'identifier'
接下来,我们继续拆开body
我们发现,body其实是一个BlockStatement(块状域)对象,用来表示是{return a + b}
打开Blockstatement,里面藏着一个ReturnStatement(Return域)对象,用来表示return a + b
继续打开ReturnStatement,里面是一个BinaryExpression(二项式)对象,用来表示a + b
继续打开BinaryExpression,它成了三部分,left,operator,right
就这样,我们把一个简单的add函数拆解完毕,用图表示就是
看!抽象语法树(Abstract Syntax Tree),的确是一种标准的树结构。
那么,上面我们提到的Identifier、Blockstatement、ReturnStatement、BinaryExpression, 这一个个小部件的说明书去哪查?
送给你的AST螺丝刀:recast
输入命令:
npm i recast -S
你即可获得一把操纵语法树的螺丝刀
接下来,你可以在任意js文件下操纵这把螺丝刀,我们新建一个parse.js示意:
parse.js
// 给你一把"螺丝刀"——recast
const recast = require("recast");
// 你的"机器"——一段代码
// 我们使用了很奇怪格式的代码,想测试是否能维持代码结构
const code =
function add(a, b) {
return a +
// 有什么奇怪的东西混进来了
// 用螺丝刀解析机器
const ast = recast.parse(code);
// ast可以处理很巨大的代码文件
// 但我们现在只需要代码块的第一个body,即add函数
const add = ast.program.body[0]
console.log(add)
输入node parse.js你可以查看到add函数的结构,与之前所述一致,通过AST对象文档可查到它的具体属性: