[转] eval() may be evil
eval()这个东东,以前也接触过和用过,但是一直没放在心上去理解。今天偶然发现了一篇文章,才让我恍然大悟,其实eval()就是把一个字符串当做代码来执行的。这也就引出了引文中提到的问题:eval() 如果不善用的话,会给自己的程序带来很大的问题,
-------引文原文如下:---------------------------
Simon Willison 认为:虽然Javascript提供了把动态字符串作为脚本代码来执行的 eval() 函数,为代码的编写提供了很多的便利,但同时也导致了代码执行效率的低下以及难以维护。通常来说,只有设计存在缺陷才会不得不用 eval() 来弥补这些缺陷。
对于 eval() 的使用最常见的错误是用来动态获取某个对象/子对象及其属性。假设你的代码中有一个对象foo,其属性将在运行时被决定。你可能会想用eval来解决这个问题:
1. var property = 'bar';
2.
3. var value = eval('foo.' + property);
4.
这样做固然可以达到预期的效果,但这会导致JavaScript每次运行这段代码的时候都切换到解释器模式来重新解释这段动态构建的代码,其运行效率大大降低。实际上以上情况你可以完全回避使用eval():
1. var property = 'bar';
2.
3. var value = foo[property];
4.
另一方面,使用 eval() 也可能会导致一些潜在的安全隐患。这一点对于任何语言来说都是如此。当你通过页面的GET/POST参数来获取数据并 eval() 之的时候,就有可能被恶意用户利用来注入非法代码进行非预期的操作。所以,无论是从执行效率、代码维护成本还是应用安全性角度考虑,对于 eval() 的使用都必须谨慎。回想自己曾经写过的那些代码,有段时间里面 eval() 简直被我给用滥了 -- 最直接的后果就是给接手的其他程序员造成了不小的麻烦。要弄懂一段动态组合出来的字符串到底被 eval() 之后是用来干什么的的确不像结构清晰的OO代码那么容易。
难怪有人认为 eval() 应该被完全从编程语言中被清理出去,因为 eval() 意味着 B.A.D. -- Broken As Designed 。这个情形有点像 goto 关键字。不知道有多少人对 goto 深恶痛绝,也不知道 goto 导致了多少代码的崩溃。但不可否认,仍然有很多精彩的 goto 使用范例。只要用在合适的地方, eval() 同样可以是不二的解决方案。比如Ajax中用来执行XMLHttpRequest得到的服务器端响应:
1. function evalRequest(url) {
2.
3. var xmlhttp = new XMLHttpRequest();
4.
5. xmlhttp.onreadystatechange = function() {
6.
7. if (xmlhttp.readyState==4 && xmlhttp.status==200) {
8.
9. eval(xmlhttp.responseText);
10.
11. }
12.
13. }
14.
15. xmlhttp.open("GET", url, true);
16.
17. xmlhttp.send(null);
18.
19. }