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

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

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


当前回答

让我们看看真正的人:

现在每个主流浏览器都有一个内置的控制台,你想成为黑客的人可以使用它来调用任何值的任何函数-为什么他们会麻烦使用eval语句-即使他们可以? 如果编译2000行JavaScript需要0.2秒,那么如果我计算4行JSON,性能会下降多少?

即使克罗克福德对“eval是邪恶的”的解释也很软弱。

eval是邪恶的,eval函数是最被滥用的功能 JavaScript。避免它

正如克罗克福德自己可能会说的那样:“这种说法往往会产生非理性的神经症。别买它。”

理解eval并知道它什么时候可能有用更重要。例如,eval是评估软件生成的服务器响应的明智工具。

顺便说一句:Prototype.js直接调用eval 5次(包括在evalJSON()和evalResponse()中)。jQuery在parseJSON中使用它(通过函数构造函数)。

其他回答

什么时候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对于代码生成很有用。

举个愚蠢的例子,如果你正在编写一个Brainfuck编译器,你可能想要构造一个函数,它以字符串的形式执行指令序列,并对它进行eval以返回一个函数。

让我们看看真正的人:

现在每个主流浏览器都有一个内置的控制台,你想成为黑客的人可以使用它来调用任何值的任何函数-为什么他们会麻烦使用eval语句-即使他们可以? 如果编译2000行JavaScript需要0.2秒,那么如果我计算4行JSON,性能会下降多少?

即使克罗克福德对“eval是邪恶的”的解释也很软弱。

eval是邪恶的,eval函数是最被滥用的功能 JavaScript。避免它

正如克罗克福德自己可能会说的那样:“这种说法往往会产生非理性的神经症。别买它。”

理解eval并知道它什么时候可能有用更重要。例如,eval是评估软件生成的服务器响应的明智工具。

顺便说一句:Prototype.js直接调用eval 5次(包括在evalJSON()和evalResponse()中)。jQuery在parseJSON中使用它(通过函数构造函数)。

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

当你相信消息来源时。

在JSON的情况下,它或多或少很难篡改源代码,因为它来自你控制的web服务器。只要JSON本身不包含用户上传的数据,使用eval就没有什么大的缺点。

在所有其他情况下,在将用户提供的数据提供给eval()之前,我将竭尽全力确保它符合我的规则。