小编典典

JavaScript 的 eval() 什么时候不是邪恶的?

all

我正在编写一些 JavaScript 代码来解析用户输入的函数(用于类似电子表格的功能)。解析公式后,我 可以 将其转换为 JavaScript
并在其上运行eval()以产生结果。

但是,如果我可以避免它,我总是回避使用eval()它,因为它是邪恶的(而且,无论对错,我一直认为它在 JavaScript
中更加邪恶,因为要评估的代码可能会被用户更改)。

那么,什么时候可以使用呢?


阅读 97

收藏
2022-04-27

共1个答案

小编典典

我想花点时间来解决您问题的前提- eval() 是“ 邪恶 的”。编程语言人们使用的“ 邪恶
”一词通常意味着“危险”,或者更准确地说是“能够用一个看起来很简单的命令造成很多伤害”。那么,什么时候可以使用危险的东西呢?当您知道危险是什么并采取适当的预防措施时。

言归正传,让我们看看使用 eval() 的危险。和其他所有事情一样,可能存在许多小的隐患,但是两个大风险 - eval() 被认为是邪恶的原因 -
是性能和代码注入。

  • 性能 - eval() 运行解释器/编译器。如果您的代码被编译,那么这是一个很大的打击,因为您需要在运行时调用一个可能很重的编译器。然而,JavaScript 仍然主要是一种解释性语言,这意味着调用 eval() 在一般情况下不会对性能造成很大影响(但请参阅下面我的具体说明)。
  • 代码注入 - eval() 可能在提升的权限下运行一串代码。例如,以管理员/root 身份运行的程序永远不会想要 eval() 用户输入,因为该输入可能是“rm -rf /etc/important-file”或更糟。同样,浏览器中的 JavaScript 不存在这个问题,因为该程序无论如何都在用户自己的帐户中运行。服务器端 JavaScript 可能有这个问题。

关于你的具体情况。据我了解,您是自己生成字符串,所以假设您小心不允许生成像“rm -rf something-
important”这样的字符串,没有代码注入风险(但请记住,它 _非常非常在一般情况下
很难_确保这一点)。另外,如果你在浏览器中运行,那么代码注入风险很小,我相信。

至于性能,您必须权衡它与编码的易用性。我认为,如果您正在解析公式,您不妨在解析期间计算结果,而不是运行另一个解析器(eval() 中的那个)。但是使用
eval() 编码可能更容易,并且性能损失可能不明显。在这种情况下,看起来 eval() 并不比任何其他可能为您节省时间的函数更邪恶。

2022-04-27