JavaScript中eval的预期目的是什么?

时间:2009-10-20 11:41:49

标签: javascript

  

可能重复:
  When is JavaScript’s eval() not evil?

我知道,一般使用eval()是不好的做法。

但是出于什么目的它存在?

eval()的正确目的是什么?

在什么情况下最好使用eval()

5 个答案:

答案 0 :(得分:8)

<强> eval

  

评估一串JavaScript代码   没有提到特定的   对象

如果将算术表达式构造为字符串,则可以使用eval稍后对其进行求值。例如,假设您有一个变量x。您可以通过将表达式的字符串值(例如“3 * x + 2”)分配给变量,然后在脚本中稍后调用eval来推迟对涉及x的表达式的求值。

使用eval时要小心

eval()是一个危险的函数,它使用调用者的特权执行它传递的代码。如果您使用可能受恶意方影响的字符串运行eval(),您最终可能会使用您的网页/扩展程序的权限在用户的计算机上运行恶意代码。

答案 1 :(得分:8)

eval()提供对JavaScript编译器的访问,这最终允许代码在以后执行。传递给函数的参数将传递给JavaScript编译器,然后执行代码。

开发人员争论eval()的安全性。 的安全性较低,但是如果你确定你的输入在传递之前已经消毒了,那么这应该不是问题。

此外,eval()的结果通常较慢,因为代码尚未编译或缓存。使用该功能显然会受到性能影响。

使用eval()调试代码也很困难,因为关于最终执行的代码几乎没有上下文信息(想想行号)。

就Web开发而言,eval()当前最流行的用途之一是在Ajax应用程序的上下文中反序列化通常的JSON字符串;但是,这并不是说没有太多其他用途。

答案 2 :(得分:2)

您可能需要查看this article,以下是该页面的直接引用,它总结了eval的功效。

  

JavaScript EVAL命令可以   使用动态时非常强大   基于Web的应用程序中的内容。   EVAL可以减少代码和缓解   与未知数据的交互   在加载时,但有缺点   考虑到。

     

这个命令的真正力量就是它   处理非数据的能力   在加载时已知 - 例如,   用户输入的数据。就像我一样   提到,EVAL接受任何字符串   你提供并执行它返回   结果,如果适用的话。您   可以用它来执行JavaScript   你被问到的地方   在加载时不知道执行。对于   例如,如果我们有一个计算   提供等式的脚本   由用户返回结果,你   可以使用EVAL来执行   计算

答案 3 :(得分:1)

我认为使用它是危险的并不是那么糟糕。人们说不要使用eval因为它打开了滥用的漏洞。如果输入是安全的,可以使用它。例如,在使用正则表达式检查输入以确保没有“危险”内容之后,它在Doug Crockford's JSON parser中使用。

人们告诉你不要使用它的另一个原因是,如果你使用eval太多,人们会开始称你为Eval Knievel。

答案 4 :(得分:0)

我最近尝试使用eval()命令,同时尝试为新项目提出新约定。

我想要的是:我喜欢拥有私有公共特权方法的想法,ala。 Doug Crockford's article,但我希望能够在我的课程的顶部公开方法/变量,而不是像往常那样在底部公开。

考虑一下:

var Singleton = function() {
    // Private
    function _one() {
        // code...
    }

    function _two() {
        // code...
    }

    // Public
    return {
        one: _one,
        two: _two
    };
}();

有三个eval()(两个嵌套在主要内部)我能够有这样的语法:

var Singleton = function() {
    // Public
    var $interface = {
        one: $forward,
        two: $forward
    };

    // Private
    function _one() {
        // code...
    }

    function _two() {
        // code...
    }

    // This does the magic
    return eval($init);
}('Singleton');

不顾一切和常识,它确实有效。 (请注意,我还想要一种调试命名空间的方法,这就是为什么你可以看到传递给单例的字符串的原因。$init也照顾到了这一点。)

无论如何,我认为输入所有这些的意思是说eval()不一定是不惜一切代价应该避免的JavaScript垃圾的病态粪便,并且可以用于更多方式而不仅仅是on(trusted!)从服务器发送的代码和JSON反序列化。

(虽然在我的情况下它最终是一个心理锻炼,因为我已经说服自己不要打扰私有方法/变量,只是使用严格的命名空间约定。)