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

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

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


当前回答

我相信eval对于客户端web应用程序来说是一个非常强大的功能,并且是安全的。和JavaScript一样安全,但JavaScript不安全。:-)安全问题本质上是服务器端的问题,因为现在,使用像Firebug这样的工具,你可以攻击任何JavaScript应用程序。

其他回答

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

当您使用解析函数解析JSON结构时(例如,jQuery.parseJSON),它期望JSON文件的完美结构(每个属性名都用双引号括起来)。然而,JavaScript更加灵活。因此,可以使用eval()来避免它。

让我们看看真正的人:

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

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

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

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

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

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

我的使用eval: import的例子。

通常的做法。

var components = require('components');
var Button = components.Button;
var ComboBox = components.ComboBox;
var CheckBox = components.CheckBox;
...
// That quickly gets very boring

但是在eval和一个小helper函数的帮助下,它得到了更好的外观:

var components = require('components');
eval(importable('components', 'Button', 'ComboBox', 'CheckBox', ...));

Importable可能看起来像这样(此版本不支持导入具体成员)。

function importable(path) {
    var name;
    var pkg = eval(path);
    var result = '\n';

    for (name in pkg) {
        result += 'if (name !== undefined) throw "import error: name already exists";\n'.replace(/name/g, name);
    }

    for (name in pkg) {
        result += 'var name = path.name;\n'.replace(/name/g, name).replace('path', path);
    }
    return result;
}

只要可以确定代码的源代码来自您或实际用户,就没有理由不使用eval()。尽管他可以操纵发送到eval()函数的内容,但这并不是一个安全问题,因为他能够操纵网站的源代码,因此可以改变JavaScript代码本身。

所以…何时不使用eval()?Eval()只应该在第三方有可能更改它的情况下才使用。比如拦截客户端和服务器之间的连接(但如果这是一个问题,请使用HTTPS)。你不应该用eval()来解析别人写的代码,比如在论坛上。