一看就懂的JS抽象语法树
关注“重度前端”
助力前端深度学习
━━━━━
前言
babel是现在几乎每个项目中必备的一个东西,在我们的开发中频繁被使用。了解其工作原理势必让我们对他的使用更加的顺畅和清晰。本文不会太过深入的介绍实现原理,只是有个初步的了解即可。对实现机制有兴趣的同学可以深入的研究。
babel有引擎babylon,早期fork了项目acron,了解这个之前我们先来看看这种引擎解析出来是什么东西。不光是babel还有webpack等都是通过javascript parser将代码转化成抽象语法树,这棵树定义了代码本身,通过操作这颗树,可以精准的定位到赋值语句、声明语句和运算语句。
什么是抽象语法树
我们可以来看一个简单的例子:
var a = 1;
var b = a + 1;
我们通过这个网站,他是一个esprima引擎的网站,十分好用.画成流程图如下:
而他的json对象格式是这样的:
{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "a"
},
"init": {
"type": "Literal",
"value": 1,
"raw": "1"
}
}
],
"kind": "var"
},
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "b"
},
"init": {
"type": "BinaryExpression",
"operator": "+",
"left": {
"type": "Identifier",
"name": "a"
},
"right": {
"type": "Literal",
"value": 1,
"raw": "1"
}
}
}
],
"kind": "var"
}
],
"sourceType": "script"
}
众多的引擎
chrome有v8,firefix有spidermonkey.还有一些常用的引擎有:
esprima
acron
Traceur
UglifyJS2
shift
下面是一些引擎的速度对比,以及用不同的框架,引擎们的加载速度:
我个人认为,封装的越完美的,其实解析的时间更长,引擎之间也是acron这个速度比较优秀,babel引擎前身就是fork这个项目的。
AST的三板斧
通过esprima生成AST
通过estraverse遍历和更新AST
通过escodegen将AST重新生成源码
我们可以来做一个简单的例子:
1.先新建一个test的工程目录
2.在test工程下安装esprima、estraverse、escodegen的npm模块
npm i esprima estraverse escodegen --save
3.在目录下面新建一个test.js文件,载入以下代码:
const esprima = require('esprima');
let code = 'const a = 1';
const ast = esprima.parseScript(code);
console.log(ast);
你将会看到输出结果:
Script {
type: 'Program',
body:
[ VariableDeclaration {
type: 'VariableDeclaration',
declarations: [Array],
kind: 'const' } ],
sourceType: 'script' }
4.再在test文件中,载入以下代码:
const estraverse = require('estraverse');
estraverse.traverse(ast, {
enter: function (node) {
node.kind = "var";
}
});
console.log(ast);
输出的结果:
Script {
type: 'Program',
body:
[ VariableDeclaration {
type: 'VariableDeclaration',
declarations: [Array],
kind: 'var' } ],
sourceType: 'script' }
5.最后在test文件中,加入以下代码:
const escodegen = require("escodegen");
const transformCode = escodegen.generate(ast)
console.log(transformCode);
输出的结果:
var a = 1;
通过这三板斧:我们将const a = 1
转化成了var a = 1
想想是不是babel也是这样实现的呢?其实所有的涉及到代码转换的都是这个原理啦。只是实现的方式不同。
推荐网站以及工具
esprima源码
acron源码
speed comparison
AST explorer
esprima可视化
在线可视化AST
总结
抽象树在前端用的很多很多,现在流行的工具,不管是webpack还是babel都会通过那个三板斧的流程,实际的处理会非常的复杂,这里我只是大致介绍一下。我们可以将这个技术用到实际的工作,从工作中发现痛点,实现自己的js编译工具。有兴趣的也可以把esprima的源码看一下,为什么是esprima呢,因为esprima的资料比较多,而acron比较轻量级。
原文地址:https://segmentfault.com/a/1190000012943992
【点个赞或者分享下,我就干的更带劲儿】
重度前端--助力深度学习
为web前端同行提供有价值、有深度的技术文章
官网:http://bigerfe.com【建设】
长按二维码关注我
一看就懂的JS抽象语法树相关推荐
- JS抽象语法树AST基础学习
点击上方"Python学习开发",选择"加为星标" 第一时间关注Python技术干货! 原文:http://www.goyth.com/2018/12/23/A ...
- 抽象语法树 c语言,一个简单的例子看懂抽象语法树的魔力
在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示.它以树状的形式表现编程语言的语法结构,树上的每个 ...
- 基于Python的JS逆向和AST抽象语法树
一.关于js逆向的一些知识点总结 javascript-数据类型中,null,undefinded都表示没有东西 普通函数,匿名函数,构造函数,一般常见的是匿名函数 函数可以当成字符串看待,可以看成参 ...
- js 数组 实现 完全树_JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧
摘要: JS的"编译原理". 原文:JavaScript的工作原理:解析.抽象语法树(AST)+ 提升编译速度5个技巧 作者:前端小智 Fundebug经授权转载,版权归原作者所有 ...
- js最小化浏览器_「译」解析、抽象语法树(ast) +如何最小化解析时间的5个技巧...
前言 该系列课程会在本周陆续更新完毕,主要讲解的都是工作中可能会遇到的真实开发中比较重要的问题以及相应的解决方法.通过本系列的课程学习,希望能对你日常的工作带来些许变化.当然,欢迎大家关注我,我将持续 ...
- 理解Babel是如何编译JS代码的及理解抽象语法树(AST)
Babel是如何编译JS代码的及理解抽象语法树(AST) 1. Babel的作用是? 很多浏览器目前还不支持ES6的代码,但是我们可以通过Babel将ES6的代码转译成ES5代码,让所有的浏览器 ...
- 抽象语法树 Abstract syntax tree
什么是抽象语法树? 在计算机科学中,抽象语法和抽象语法树其实是源代码的抽象语法结构的树状表现形式 在线编辑器 我们常用的浏览器就是通过将js代码转化为抽象语法树来进行下一步的分析等其他操作.所以将js ...
- JavaScript 是如何工作的:解析、抽象语法树(AST)+ 提升编译速度5个技巧
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
- 详解AST抽象语法树
浅谈 AST 先来看一下把一个简单的函数转换成AST之后的样子. // 简单函数 function square(n) {return n * n; }// 转换后的AST {type: " ...
最新文章
- bootstrap Table API和一些简单使用方法
- Android 程序自动更新功能模块实现
- [转]我们需要IQ吗?--敬以此文献给和我一样迷茫,浮躁的人,共勉!
- 成功解决pandas读取文件中不读取第一索引列
- 根据当前时间如何找到上月的第一天和最后一天?
- kafka系列文章索引
- 介绍TCP/udp比较好的博客
- HTTP 协议演示——HTTP 协议概述(3-5)
- Python之数据分析(间接联合排序、所有最值相关函数、有序插入、定积分、插值器对象)
- mysql 主从复制 gtid_Mysql-GTID主从复制
- Android【报错】android.content.ActivityNotFoundException:activity in yourAndroidManifest.?
- java除,小数的问题
- 小学计算机老师师德师风演讲稿,2015年小学教师师德师风演讲稿
- 文字和表单(checkbox/radio)元素垂直对齐方法,兼容Firefox和IE。
- 打印机上的一款驱动-惠普LaserJet1020Plus打印机驱动提供下载
- 介绍几款可以在手机上用来学习编程的软件
- [LeetCode-java实现]3. 无重复字符的最长子串
- 运营商常见的大数据业务学习笔记
- 对于分布式集群,应该思考什么问题?
- php语言缺点,php语言优缺点分析
热门文章
- 【目标管理】OKR如何助力目标管理?
- 十八、从Django入手
- 威纶触摸屏键盘不显示数字_威纶触摸屏功能键使用教程
- Docker搭建持续集成平台jira
- C/S和B/S架构总结
- WebRTC错误[1]Failed to set remote answer sdp: Called in wrong state: stable
- 精通Web Analytics 2.0 (10) 第八章:竞争情报分析
- 5个方法助设计师保持创造力
- 7.12~7.13学习感悟
- 10.25软件测试学习总结