eval函数是一种强大而简单的动态生成代码的方法,那么有什么注意事项呢?


当前回答

随着带有JavaScript编译器的下一代浏览器问世,这可能会成为一个更大的问题。通过Eval执行的代码在这些新浏览器上的表现可能不如JavaScript的其他部分。应该有人来做侧写。

其他回答

除非让eval()成为动态内容(通过cgi或输入),否则它就像页面中所有其他JavaScript一样安全可靠。

Eval并不总是邪恶的。有些时候,这是非常合适的。

然而,eval在当前和历史上都被那些不知道自己在做什么的人过度使用。不幸的是,这包括编写JavaScript教程的人,在某些情况下,这确实会产生安全后果——或者,更常见的是,简单的错误。所以,我们在eval上加的问号越多越好。任何时候你使用eval你都需要检查你正在做的事情,因为你可能会用一种更好,更安全,更干净的方式来做。

举一个非常典型的例子,设置id存储在变量'potato'中的元素的颜色:

eval('document.' + potato + '.style.color = "red"');

如果上面这类代码的作者对JavaScript对象工作的基本原理有所了解,他们就会意识到可以使用方括号来代替字面上的点名称,从而消除了eval的需要:

document[potato].style.color = 'red';

...这更容易阅读,也更少潜在的错误。

(但是,那些/真正/知道自己在做什么的人会说:

document.getElementById(potato).style.color = 'red';

这比直接从文档对象中访问DOM元素更可靠。)

我不会试图反驳之前所说的任何事情,但我将提供eval()的这种用法,(据我所知)不能以任何其他方式完成。可能还有其他方法来编码,也可能有其他方法来优化它,但这是直接完成的,为了清晰起见,没有任何花哨的东西来说明eval的使用,这真的没有任何其他选择。也就是说:动态(或者更准确地说)编程创建的对象名称(相对于值)。

//Place this in a common/global JS lib:
var NS = function(namespace){
    var namespaceParts = String(namespace).split(".");
    var namespaceToTest = "";
    for(var i = 0; i < namespaceParts.length; i++){
        if(i === 0){
            namespaceToTest = namespaceParts[i];
        }
        else{
            namespaceToTest = namespaceToTest + "." + namespaceParts[i];
        }

        if(eval('typeof ' + namespaceToTest) === "undefined"){
            eval(namespaceToTest + ' = {}');
        }
    }
    return eval(namespace);
}


//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
  //Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
    //Code goes here
    //this.MyOtherMethod("foo"));  // => "foo"
    return true;
}


//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);

编辑:顺便说一下,我不建议(出于之前指出的所有安全原因)根据用户输入来确定对象名称。但我想不出你有什么理由这么做。不过,我还是想指出这不是一个好主意:)

如果您正在执行用户提交的代码,除了可能存在的安全问题之外,大多数情况下,有一种更好的方法,无需在每次执行时都重新解析代码。匿名函数或对象属性可以替代eval的大部分用途,而且更安全、更快。

这可能存在安全风险,它具有不同的执行范围,并且效率非常低,因为它为代码的执行创建了一个全新的脚本环境。更多信息请参见这里:eval。

不过,它非常有用,适度使用可以添加许多很好的功能。