eval是什么,为什么它被视为“邪恶的”?

6
var myString = "x",
    myObject = {
        x: 10
    },
value = eval("myObject." + myString);
alert(value)
alert(myObject[myString]);

eval是有害的

我在网上读到了关于eval()函数的信息,但除了"它评估表达式"之外,我实际上并没有真正理解它的作用。

我们应该只针对数值使用eval()函数吗?


请查看右侧的相关问题。 - devnull
2个回答

14

eval()将其接收到的字符串视为普通的JavaScript代码来运行。

它被认为是“邪恶的”,因为:

  • 它使事情过于复杂 - 大多数使用eval()的情况下,都有更简单的解决方案不需要它。本问题中的示例就是一个完美的例子:对于这样的表达式,没有任何需要使用eval()的必要。JS已经有了完全适用的语法来引用一个对象属性名作为字符串(myObject["x"]myObject.x相同)。

  • 它更难调试 - 在调试器中更难处理它,即使你已经成功弄清楚了发生了什么,你还需要额外的工作来调试原始字符串生成代码和eval()后的代码。

  • 它会减慢运行速度 - 脚本编译器无法预编译eval()中的代码,因为它不知道代码包含什么直到执行时才能确定。因此,现代Javascript引擎的一些性能优势将不再存在。

  • 它是黑客的梦想 - eval()将一个字符串作为代码运行。黑客喜欢这个功能,因为将字符串注入到程序中比注入代码容易得多;但是,eval()意味着你可以将一个字符串注入到程序中,并让它作为代码运行。因此,eval()使您的代码更容易被黑客攻击。(对于基于浏览器的JavaScript来说,这不是那么大的问题,因为JS代码在浏览器中是可访问的,所以您的安全模型不应该基于您的代码不可变,但是注入攻击仍然可能成为一个问题,特别是跨站点攻击)。


6
在这种情况下,只需使用myObject[myString]eval的使用非常不当。我发现它几乎唯一有效的用途是在较旧的浏览器中解析JSON。

1
它似乎非常强大,可以创建自修改的类json文件,存储功能和数据。例如,您可以创建一个服务器,通过检查是否存在所需功能('functionality' in parsedObject),并且如果不存在,则可以让客户端将该方法教给该对象来“学习”。这反过来允许创建“活的库”,通过消息教授事物而不是编辑代码来使它们增长。我认为eval不是邪恶的,而是最强大的javascript结构。 - Dmytro
有趣的是,JavaScript 的 eval 比 PHP 更强大,因为 JavaScript 能够打印非本地函数的代码,所以只要不是本地函数,就可以将对象转换回字符串。而在 PHP 中,你无法这样做,因此要实现自我编写的 PHP 代码更难,而在 JavaScript 中,读取对象、将想要的方法转换为字符串、进行更改、将其放回字符串并将更改写入对象和文件非常简单,可以有效地实现自我编写的代码。 - Dmytro
这种评估的演示可以在http://hastebin.com/eyacegaduq.coffee找到。 - Dmytro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接