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


当前回答

这大大降低了您对安全性的信心。

其他回答

我不会试图反驳之前所说的任何事情,但我将提供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在当前和历史上都被那些不知道自己在做什么的人过度使用。不幸的是,这包括编写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()从XMLHttpRequest返回到您自己的站点的某个JSON中创建一个对象,该对象是由受信任的服务器端代码创建的,那么这可能不是问题。

不可信的客户端JavaScript代码无论如何也做不了那么多。只要你执行eval()的对象来自一个合理的源,就没问题。

需要记住的一件事是,您可以经常使用eval()在其他受限制的环境中执行代码——阻塞特定JavaScript函数的社交网站有时可以通过在eval块中分解它们来愚弄它们

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

因此,如果你想运行一些JavaScript代码,否则它可能是不允许的(Myspace,我看着你…),那么eval()可能是一个有用的技巧。

然而,由于上面提到的所有原因,你不应该在你自己的代码中使用它,在那里你有完全的控制权——这是没有必要的,最好把它归到“棘手的JavaScript hacks”架子上。

我想说的是,如果你在javascript中使用eval()并不重要,因为它是在浏览器中运行的。

所有现代浏览器都有一个开发者控制台,在那里你可以执行任意的javascript,任何半聪明的开发者都可以查看你的JS源代码,并将他们需要的任何部分放入开发控制台来做他们想做的事情。

*只要你的服务器端对用户提供的值进行了正确的验证和消毒,在你的客户端javascript中解析和评估什么都不重要。

然而,如果你问在PHP中是否适合使用eval(),答案是否定的,除非你将任何可能传递给eval语句的值列入白名单。