V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
nobo
V2EX  ›  程序员

eval5 JavaScript 解释器, 1.4.0-1.4.5 发布日志

  •  
  •   nobo · 2020-04-19 10:03:31 +08:00 · 2161 次点击
    这是一个创建于 1705 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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;
        }
    }
    

    eval5

    示例

    在线体验

    更多示例

    以下是解析 echarts4 效果示例: eval5 示例

    8 条回复    2020-04-20 18:09:09 +08:00
    neilp
        1
    neilp  
       2020-04-19 11:22:51 +08:00
    性能测试过吗
    gkiwi
        2
    gkiwi  
       2020-04-19 13:19:24 +08:00
    今天还和同事扯淡,你执行这个试试:

    var a=1;{a=2;function a(){};a=3};console.info(a);
    nobo
        3
    nobo  
    OP
       2020-04-19 17:32:44 +08:00
    @gkiwi
    因为 es5 没有块级作用域,所以输出是:3
    gkiwi
        4
    gkiwi  
       2020-04-19 18:27:03 +08:00
    @nobo #3 soga !我以为输出的是 undefined 。。( https://bplok20010.github.io/eval5/)
    代码很棒!
    nobo
        5
    nobo  
    OP
       2020-04-19 18:33:53 +08:00
    @gkiwi 谢谢
    zhouyg
        6
    zhouyg  
       2020-04-20 15:45:14 +08:00
    为啥不实现可以直接执行 es6 或者 typescript 的代码?
    nobo
        7
    nobo  
    OP
       2020-04-20 18:03:19 +08:00
    @zhouyg
    es5 的语法相对少,实现会简单点,可以先将 es6 转换成 es5 。
    nobo
        8
    nobo  
    OP
       2020-04-20 18:09:09 +08:00
    @neilp
    没有,eval5 就是解析 AST 来实现,目前我也没有很好的优化方案。如果相比 js 的 eval 肯定是远远不如。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5490 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:53 · PVG 09:53 · LAX 17:53 · JFK 20:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.