要么孵化 要么臭掉
eval() may be evil
对于 eval() 的使用最常见的错误是用来动态获取某个对象/子对象及其属性,像这篇文章所介绍的那样。假设你的代码中有一个对象foo,其属性将在运行时被决定。你可能会想用eval来解决这个问题:
这样做固然可以达到预期的效果,但这会导致JavaScript每次运行这段代码的时候都切换到解释器模式来重新解释这段动态构建的代码,其运行效率大大降低。实际上以上情况你可以完全回避使用eval():
另一方面,使用 eval() 也可能会导致一些潜在的安全隐患。这一点对于任何语言来说都是如此。当你通过页面的GET/POST参数来获取数据并 eval() 之的时候,就有可能被恶意用户利用来注入非法代码进行非预期的操作。
所以,无论是从执行效率、代码维护成本还是应用安全性角度考虑,对于 eval() 的使用都必须谨慎。回想自己曾经写过的那些代码,有段时间里面 eval() 简直被我给用滥了 -- 最直接的后果就是给接手的其他程序员造成了不小的麻烦。要弄懂一段动态组合出来的字符串到底被 eval() 之后是用来干什么的的确不像结构清晰的OO代码那么容易。
难怪有人认为 eval() 应该被完全从编程语言中被清理出去,因为 eval() 意味着 B.A.D. -- Broken As Designed 。这个情形有点像 goto 关键字。不知道有多少人对 goto 深恶痛绝,也不知道 goto 导致了多少代码的崩溃。但不可否认,仍然有很多精彩的 goto 使用范例。只要用在合适的地方, eval() 同样可以是不二的解决方案。比如Ajax中用来执行XMLHttpRequest得到的服务器端响应:
To be, or not to be: that is the question.
