工作中有个功能想用js的eval来实现,上网搜了一把,一堆说eval不好的,总结一下,记在这里。
Eval函数是js中用来执行一段字符串的,当然前提是这段字符串的内容的是js代码。但是为什么是evil的呢,原因如下:
1、使用eval的代码不好调试。一般使用eval的地方,代码都是动态生成的,虽然动态生成具有很大的灵活性,但是一旦出错,很难找出bug在哪里,毕竟你要调试的代码没有写在静态文件里。
2、使用eval的代码不好维护。想一下,一个程序员写的代码,几个月之后回去再看,可能需要看一阵子才能明白写的是什么,如果你用eval,那么就意味着你写了一段生成代码的代码,维护起来代价就更高了。
3、性能差。eval在执行的时候意味着浏览器又要开一个解释器(实际也许不是这样,但是总需要做点什么才能让这段文本执行起来),开解释器的这个过程代价是很高的,导致性能会急剧下降。例如下面的两段代码,片段1中使用了eval,在我的chrome上执行,平均耗时在2300ms左右,片段2没有使用eval,平均耗时只有150ms左右。可见,性能差距巨大。
//片段1 var count = 1; var t1 = new Date(); for (var i = 0; i < 10000000; i++){ eval("count = count + 1;"); } var t2 = new Date(); alert(t2 - t1); //片段2 var count = 1; var t1 = new Date(); for (var i = 0; i < 10000000; i++){ count = count + 1; } var t2 = new Date(); alert(t2 - t1);
4、可能会有注入危险。设想这么一个情况,你从用户那里接收一段js代码字符串,然后在服务端使用类似于Node之类的技术来使用eval执行用户输入的代码,那么用户就完全可以写一段代码来获得你的机器控制权。
5、影响优化。现代的js解释器一般都会对js代码进行优化,但是当你的代码里有eval的时候,就意味着在执行之前这段代码是不固定的,解释器就不知道该怎么优化,所以当解释器碰到eval的时候基本就放弃优化了。
但是一直没弄明白的是,既然这玩意这么eval,那么为什么当时把他设计出来了呢?