study icon indicating copy to clipboard operation
study copied to clipboard

eval

Open cfour-hi opened this issue 6 years ago • 0 comments

eval() 是魔鬼

特性

将字符串变为可执行代码执行,同样能做到的这点的还有 Function setTimeout setInterval

缺陷

  1. 开发者工具无法进行断点调试

  2. 性能问题

    现代浏览器有两种编译模式:fast path 和 slow path,fast path 用来编译稳定和可预测代码(stable and predictable),slow path 用来便于不可预测代码。 eval 的执行的字符串代码属于不可预测代码,使用 slow path 模式。

  3. 安全问题

    容易引起 XSS 攻击,对信息源要有充分的保证和信任。

  4. 作用域问题

    eval 的字符串代码能访问到外部作用域,并且它也能对外部作用域中的变量进行修改。与此相对,Function 的字符串代码只能访问到全局作用域并且修改。

    // 使用 eval
    
    var a = 1;
    
    console.log(a); // => 1
    
    (function () {
      var a = 2;
    
      console.log(a); // => 2
    
      eval('a = 3; console.log(a);'); // => 3
    
      console.log(a); // => 3
    })();
    
    console.log(a); // => 1
    
    // 使用 Function
    
    var a = 1;
    
    console.log(a); // => 1
    
    (function () {
      var a = 2;
    
      console.log(a); // => 2
    
      Function('a = 3; console.log(a);')(); // => 3
    
      console.log(a); // => 2
    })();
    
    console.log(a); // => 3
    

总结

虽然 eval 有诸多缺陷,但也并不是没有用武之地,比如 webpack 开发环境构建提供 eval 模式加速构建,每个模块使用 eval() 执行。富文本编辑器也会有使用需求。

对于某些需要执行字符串代码的需求,依据实际需求情况分析使用 Function 还是 eval。核心在于开发人员素质,要有能力完全驾驭这两个函数,魔鬼 😈 也是可以好好利用的。


cfour-hi avatar Mar 17 '18 04:03 cfour-hi