没有eval和有eval的语言在能力上没有区别。在不支持eval的语言中,你总是可以自己实现eval,尽管在某些语言(如Lisp)中更容易,在其他语言(如C)中则更困难。这就是为什么我们知道它不会为语言增加任何新的功能。
通常认为eval“功能强大但在生产代码中却危险且不必要”。如果您的源代码经过审核,并且使用了eval,则您将不得不习惯于人们告诉您不要使用eval。通常,如果您使用eval,那么完成相同任务的更直接和更安全的方法是存在的。
安全漏洞
eval函数通常会导致安全漏洞,例如在Web应用程序中。例如,在Python中:
i = input('Enter a number> ')
Python 3.x之前版本中的input
函数会对用户输入进行求值,导致安全问题:
请输入一个数字> __import__('os').system('rm -rf $HOME') # 不要尝试此操作
在完全沙盒运行时(如JavaScript、Lua、CLI等)可以避免这种情况。然而,在非沙盒代码中,使用eval
是非常困难的。
REPL
eval
的一个重要用途是REPL,这是软件开发中非常有用的工具。在Google Chrome 中,您可以通过按Ctrl+Shift+I打开REPL - 只需在弹出的框中开始键入JavaScript即可。Firefox和Safari也都有 REPL。
为什么不包括eval
?
eval
函数通常非常复杂。将其包含在标准库中意味着库或运行时必须包含完整的语言编译器或解释器,这是一大堆代码。这就是为什么通常在通常被解释或 JIT 的语言中看到eval
- Lisp,Python和JavaScript运行时通常已经包括完整的编译器,因此eval
没有额外的负担。
C语言中的eval
实现是真正的巨兽,因此它们是可选的并且被推入库中。
eval
的编程语言是默认其用户非常愚蠢的。 - Markus Unterwaditzer