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

然而,我总是避免使用eval(),因为它是邪恶的(而且,无论正确与否,我一直认为它在JavaScript中更邪恶,因为要计算的代码可能会被用户更改)。

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


当前回答

Eval()并不坏。或者,如果是的话,它是邪恶的,就像反射、文件/网络I/O、线程和IPC在其他语言中的“邪恶”一样。

如果,出于您的目的,eval()比手动解释更快,或者使您的代码更简单,或更清楚……那么你应该使用它。如果两者都不是,那么你就不应该这么做。就这么简单。

其他回答

虽然在许多情况下,您可以通过将脚本连接在一起并动态运行来完成需要完成的任务,但您通常可以使用更强大且可维护的技术。Eval很少是正确的选择。:关联数组表示法(obj["prop"]与obj.prop相同),闭包,面向对象技术,函数技术-请使用它们。

至于客户端脚本,我认为安全性问题是一个有争议的问题。加载到浏览器中的所有内容都受到操作的影响,因此应该这样对待。当有更简单的方法来执行JavaScript代码和/或操作DOM中的对象(例如浏览器中的URL栏)时,使用eval()语句的风险为零。

javascript:alert("hello");

如果有人想操纵他们的DOM,我说swing away。防止任何类型的攻击的安全性应该始终是服务器应用程序的责任。

从实用主义的角度来看,在可以用其他方法完成任务的情况下,使用eval()没有任何好处。但是,在某些特定的情况下应该使用eval。当这样做时,它绝对可以在没有任何破坏页面的风险的情况下完成。

<html>
    <body>
        <textarea id="output"></textarea><br/>
        <input type="text" id="input" />
        <button id="button" onclick="execute()">eval</button>

        <script type="text/javascript">
            var execute = function(){
                var inputEl = document.getElementById('input');
                var toEval = inputEl.value;
                var outputEl = document.getElementById('output');
                var output = "";

                try {
                    output = eval(toEval);
                }
                catch(err){
                    for(var key in err){
                        output += key + ": " + err[key] + "\r\n";
                    }
                }
                outputEl.value = output;
            }
        </script>
    <body>
</html>

如果你可以完全控制传递给eval函数的代码,那么使用它是可以的。

唯一需要使用eval()的情况是需要动态地运行JS。我说的是你从服务器异步下载的JS…

...10次中的9次你都可以通过重构来避免这种情况。

Eval是编译的补充,编译用于代码模板。我所说的模板是指编写一个简化的模板生成器,生成有用的模板代码,从而提高开发速度。

我写了一个框架,其中开发人员不使用EVAL,但他们使用我们的框架,反过来,该框架必须使用EVAL来生成模板。

通过以下方法可以提高EVAL的性能:您必须返回一个函数,而不是执行脚本。

var a = eval("3 + 5");

它应该被组织成

var f = eval("(function(a,b) { return a + b; })");

var a = f(3,5);

缓存肯定会提高速度。

Chrome也允许调试这样的功能非常容易。

在安全性方面,是否使用eval几乎没有什么区别。

First of all, the browser invokes the entire script in a sandbox. Any code that is evil in EVAL, is evil in the browser itself. The attacker or anyone can easily inject a script node in DOM and do anything if he/she can eval anything. Not using EVAL will not make any difference. It is mostly poor server-side security that is harmful. Poor cookies validation or poor ACL implementation on the server causes most attacks. A recent Java vulnerability, etc. was there in Java's native code. JavaScript was and is designed to run in a sandbox, whereas applets were designed to run outside a sandbox with certificates, etc. that lead to vulnerabilities and many other things. Writing code for imitating a browser is not difficult. All you have to do is make a HTTP request to the server with your favourite user agent string. All testing tools mock browsers anyway; if an attacker want to harm you, EVAL is their last resort. They have many other ways to deal with your server-side security. The browser DOM does not have access to files and not a user name. In fact nothing on the machine that eval can give access to.

如果您的服务器端安全性足够坚固,任何人都可以从任何地方进行攻击,那么您就不应该担心EVAL。正如我提到的,如果EVAL不存在,攻击者就有很多工具来入侵你的服务器,而不管你浏览器的EVAL能力如何。

Eval只适用于生成一些模板,根据事先没有使用的内容进行复杂的字符串处理。例如,我更喜欢

"FirstName + ' ' + LastName"

而不是

"LastName + ' ' + FirstName"

作为我的显示名,它可以来自数据库,并且不是硬编码的。