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

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

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


当前回答

如果可能的话,只在测试期间使用。还要注意eval()比其他专门的JSON等求值器要慢得多。

其他回答

如果可能的话,只在测试期间使用。还要注意eval()比其他专门的JSON等求值器要慢得多。

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

我总是不鼓励使用eval。几乎总是有更干净和可维护的解决方案可用。Eval甚至对于JSON解析也不需要。Eval增加了维护的难度。道格拉斯·克罗克福德(Douglas Crockford)这样的大师并不赞同这一点,这不无道理。

但我发现了一个应该使用它的例子:

当你需要传递表达式时。

例如,我有一个函数,为我构造了一个通用的google.maps.ImageMapType对象,但我需要告诉它配方,它应该如何从缩放和坐标参数构造tile URL:

my_func({
    name: "OSM",
    tileURLexpr: '"http://tile.openstreetmap.org/"+b+"/"+a.x+"/"+a.y+".png"',
    ...
});

function my_func(opts)
{
    return new google.maps.ImageMapType({
        getTileUrl: function (coord, zoom) {
            var b = zoom;
            var a = coord;
            return eval(opts.tileURLexpr);
        },
        ....
    });
}

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

唯一需要使用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"

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