eval 是邪恶的问题

Posted

技术标签:

【中文标题】eval 是邪恶的问题【英文标题】:eval is evil issue 【发布时间】:2011-04-28 08:13:06 【问题描述】:

使用 JSlint 验证我的 javascript

我收到一个错误,说 eval 是邪恶的!为什么会这样?我可以使用其他替代方法吗?

这是我使用 eval 的示例,并希望有一个解决方法。

我有一个这样的数组:

var Resources = 
message_1: 'Message 1',
message_2: 'Message 2',
message_3: 'Message 3',
message_4: 'Message 4'
;

我有一个函数 (functionResult),它返回一个数字,1、2、3 或 4。所以我想在下面的代码行中获取消息以结果结尾的数组中的资源我的功能。

$('#divPresenter').html(eval($.validator.format('Resources.message_0', functionResult)));

有什么想法可以删除 eval 并替换为其他内容吗?

【问题讨论】:

能否提供您如何使用eval的代码? 如果 JSLint 提供一些关于它为什么抛出错误的详细信息,至少会很好。 【参考方案1】:

代替:

eval($.validator.format('Resources.message_0', functionResult))

只需使用:

Resources["message_" + functionResult]

JavaScript 中的所有对象都是真正的关联数组(又名哈希),点语法(a.b)只是在哈希中查找内容的语法糖(a['b'])。所以你根本不需要eval;只需将键构建为字符串,然后使用该键查找您的值。

【讨论】:

我正要发布这个,但我先构建了一个示例:boogdesign.com/examples/array.html【参考方案2】:

Link

在大多数情况下,使用 eval 就像大锤拍打苍蝇—— 它完成了工作,但也有 很大的权力。很慢,很麻烦, 并且往往会放大伤害 你搞错了。

【讨论】:

嗯,微软。这些人似乎无法安全地使用strcpy,而是使用strcpy_s 等人(顺便说一句,这是远离),所以我不确定我太看重他们的意见了:-)【参考方案3】:

它是邪恶的,因为它允许您将字符串作为代码执行,而谁知道该字符串来自哪里或它包含什么。

是的,在 99.9% 的情况下,有更好的选择(具体是什么取决于您使用 eval 的目的)。剩下的 0.1% 的时候,你真的别无选择,只能使用eval,在这种情况下,你需要格外小心。

【讨论】:

没错。如果您已经解析或以其他方式验证了字符串是安全的,那么 eval 就不是一个大问题。这就是我在答案中链接到的解析器的工作方式。为什么?也许是因为“eval”速度很快——用比 JavaScript 更低级别的语言编写,通常是 C 或 C++。【参考方案4】:

JS Lint 融合了 Douglas Crockford 认为的 JavaScript 最佳实践。他强烈反对使用的函数之一是eval。我相信他认为这是缓慢且不安全的。

可能有许多潜在的替代方案,具体取决于相关代码。如果您想发布代码中使用eval 的部分,我们可以提供更具体的建议。

【讨论】:

+1 表示没有做出一揽子断言。 evalgoto 或函数的多次返回一样邪恶(即,只有在滥用时才邪恶)。从这个意义上说,餐具和锤子也是邪恶的 :-) 一个好的工匠了解并知道他的工具的局限性和危险。【参考方案5】:

如果您尝试使用 eval 将字符串转换为 JSON 对象,不妨试试JSON parser lib(我从未使用过,但看起来很合理)。

【讨论】:

【参考方案6】:

我不完全清楚你在做什么,但它看起来像$('#divPresenter').html(eval($.validator.format('Resources.message_0', functionResult))); 可以写成$('#divPresenter').html(Resources["message_" + functionResult]);

【讨论】:

以上是关于eval 是邪恶的问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥要在 Bash 中避免使用 eval,而应该使用啥?

PHP 捕获 eval 输出

不使用 Eval 动态引用 Javascript 数组名称?

serializeArray在传递给eval之前是否会对输入进行消毒?

为啥可变结构是“邪恶的”?

AVL 树是邪恶的吗? [关闭]