JavaScript 为什么不推荐使用 eval?

关注者
391
被浏览
329,193

23 个回答

不推荐使用eval的原因有很多,

1、eval 太神秘了,以至于很多人用错。所以不推荐使用。

比如这段代码你应该见过:

然而实际上,我们可以这样写:

这并不是eval 不好而是因为容易被用错。

eval只是一个普通的函数,只不过他有一个快速通道通向编译器,可以将string变成可执行的代码。有类似功能的还有Function , setInterval 和 setTimeout。

2、 eval不容易调试。用chromeDev等调试工具无法打断点调试,所以麻烦的东西也是不推荐使用的…

3、说到性能问题,在旧的浏览器中如果你使用了eval,性能会下降10倍。在现代浏览器中有两种编译模式:fast path和slow path。fast path是编译那些稳定和可预测(stable and predictable)的代码。而明显的,eval不可预测,所以将会使用slow path ,所以会慢。

还有一个是,在使用类似于Closure Compiler等压缩(混淆)代码时,使用eval会报错。

(又慢又报错,我还推荐吗?)

4、关于安全性,我们经常听到eval是魔鬼,他会引起XSS攻击,实际上,如果我们对信息源有足够的把握时,eval并不会引起很大的安全问题。而且不光是eval,其他方式也可能引起安全问题。比如:

莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码…

所以啊,只要你的信息源不安全,你的代码就不安全。不单单是因为eval引起的。

你用eval的时候会在意XSS的问题,你越在意就越出问题,出的多了,eval就成噩梦了。

5、效率问题是程序逻辑问题。对于一些有执行字符串代码需求的程序中,不用eval而用其他方式模拟反而会带来更大的开销。

附上几篇文章:

JavaScript探秘:eval()是“魔鬼” -- 简明现代魔法

eval是魔鬼。

eval() isn’t evil, just misunderstood

eval不是魔鬼。

到底是不是魔鬼,看看再做决定吧~

哦,看到一些说json.parse内部是用eval的,再附上几个链接供大家参考。

javascript - Does JSON.parse() use eval() internally?

这是json.parse 源码,大家也且看看娱乐下:

code.google.com/p/v8/so

eval 好不好取决于怎么使用它,一般认为的缺点:

1. 可读性非常差

2. 不好再做优化和编译

3. 会轻微增加性能消耗

4. 不安全,比如 eval input 的值

考虑 eval 的时候认为所有的问题不用 eval 都可以解决的,比如给 obj.prop1, obj.prop2 …… 这序列赋值,可以 obj[prop + 'index'] = 'xxx' 。

然后确实不能解决问题的时候再用,其实 eval 也没那么烂,因为 ECMA 5 内置的 JSON.parse 内部也是用 eval,包括 jQuery 的 parseJSON 也用 eval。