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的大部分用途,而且更安全、更快。
我想说的是,如果你在javascript中使用eval()并不重要,因为它是在浏览器中运行的。
所有现代浏览器都有一个开发者控制台,在那里你可以执行任意的javascript,任何半聪明的开发者都可以查看你的JS源代码,并将他们需要的任何部分放入开发控制台来做他们想做的事情。
*只要你的服务器端对用户提供的值进行了正确的验证和消毒,在你的客户端javascript中解析和评估什么都不重要。
然而,如果你问在PHP中是否适合使用eval(),答案是否定的,除非你将任何可能传递给eval语句的值列入白名单。
我想到两点:
安全性(但只要您自己生成要计算的字符串,这可能就不是问题) 性能:除非要执行的代码是未知的,否则无法进行优化。(关于javascript和性能,当然是Steve Yegge的演示)
我相信这是因为它可以从字符串执行任何JavaScript函数。使用它可以使人们更容易向应用程序中注入恶意代码。
需要记住的一件事是,您可以经常使用eval()在其他受限制的环境中执行代码——阻塞特定JavaScript函数的社交网站有时可以通过在eval块中分解它们来愚弄它们
eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');
因此,如果你想运行一些JavaScript代码,否则它可能是不允许的(Myspace,我看着你…),那么eval()可能是一个有用的技巧。
然而,由于上面提到的所有原因,你不应该在你自己的代码中使用它,在那里你有完全的控制权——这是没有必要的,最好把它归到“棘手的JavaScript hacks”架子上。