eval5 是基于 TypeScript 编写的 JavaScript 解释器,100%支持 ES5 语法。
支持浏览器、node.js 、小程序等 JavaScript 运行环境 。
项目地址: https://github.com/bplok20010/eval5
使用场景
- 浏览器环境中需要沙盒环境来执行 JavaScript 代码
- 浏览器环境控制代码执行时长
- 不支持 eval/Function 的 JavaScript 运行环境,如:微信小程序
更新日志
1.4.5
- 修复 with 语句中函数调用时丢失 this 信息
1.4.4
- 修复在未使用 try-catch 情况下出现异常时导致下次调用 evaluate 时的变量声明错乱问题。
1.4.3
- 修复 WithStatement 中赋值不生效问题。
- rootContext 创建调整为:Object.create(options.rootContext),防污染。
1.4.2
- 新增内置对象:URIError RangeError SyntaxError ReferenceError
- 修复 assignment 表达式触发对象的 getter 方法调用
1.4.1
- 修复再次执行事超时机制失效问题
- 修复函数表达式赋值时引起的返回值错乱问题
1.4.0
- 解释器内部 eval/Function 重写
- 新增参数 options.rootContext
- 新增参数 options.globalContextInFunction
- 移除 Interpreter.rootContext
运行原理
eval5 先将源码编译得到树状结构的抽象语法树(AST)。
抽象语法树由不同的节点组成,每个节点的 type 标识着不同的语句或表达式,例如: 1+1 的抽象语法树
{
"type": "Program",
"body": [
{
"type": "ExpressionStatement",
"expression": {
"type": "BinaryExpression",
"operator": "+",
"left": {
"type": "Literal",
"value": 1,
"raw": "1"
},
"right": {
"type": "Literal",
"value": 1,
"raw": "1"
}
}
}
],
"sourceType": "script"
}
根据节点 type 编写不同的处理模块并得到最终结果。例如:根据 1+1 的语法树我们可以写出一下解释器代码:
function handleBinaryExpression(node) {
switch( node.operator ) {
case '+':
return node.left.value + node.right.value;
case '-':
return node.left.value - node.right.value;
}
}
示例
以下是解析 echarts4 效果示例: