一尘不染

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

javascript

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

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

那么,何时可以使用它呢?


阅读 638

收藏
2020-04-22

共1个答案

一尘不染

我想花点时间解决您提出问题的前提-eval()是“ evil”。编程语言人员所用的“ evil”
一词通常表示“危险”,或更确切地说,“使用简单的命令即可造成很多伤害”。那么,什么时候可以使用危险的东西呢?当您知道危险所在以及采取适当的预防措施时。

到目前为止,让我们看一下使用eval()的危险。就像其他所有事物一样,可能存在许多小的隐患,但是性能和代码注入是两个大隐患-eval()被认为是邪恶的原因。

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

根据您的具体情况。据我了解,您是在自行生成字符串,因此,假设您谨慎地不允许生成“ rm -rf something-
important”之类的字符串,就不会有代码注入的风险(但是请记住,这 非常非常 在一般情况下 很难
确保这一点)。另外,我相信,如果您正在浏览器中运行,则代码注入的风险很小。

至于性能,您必须权衡其易编码性。我认为,如果要解析公式,则最好在解析过程中计算结果,而不是运行另一个解析器(eval()内部的那个)。但是使用eval()进行编码可能会更容易,并且性能下降可能不会引起注意。在这种情况下,eval()看起来比其他任何可以节省您时间的函数都更加evil。

2020-04-22