很多人不推荐使用eval,不推荐使用eval的原因有很多:
1、eval 太神秘了,以至于很多人用错。所以不推荐使用。
比如这段代码:
function isChecked(optionNumber){
return eval('forms[0].option' + optionNumber + '.checked');
}
var result = isChecked(1);
其实可以这样写:
function isChecked(optionNumber){
return forms[0]['option' + optionNumber].checked;
}
var result = isChecked(1);
这并不是eval 不好而是因为容易被用错。
eval只是一个普通的函数,只不过他有一个快速通道通向编译器,可以将string变成可执行的代码。有类似功能的还有Function , setInterval 和 setTimeout。 2、 eval不容易调试。用chromeDev等调试工具无法打断点调试,所以麻烦的东西也是不推荐使用的… 3、说到性能问题,在旧的浏览器中如果你使用了eval,性能会下降10倍。在现代浏览器中有两种编译模式:fast path和slow path。fast path是编译那些稳定和可预测(stable and predictable)的代码。而明显的,eval不可预测,所以将会使用slow path ,所以会慢。 还有一个是,在使用类似于Closure Compiler等压缩(混淆)代码时,使用eval会报错。 (又慢又报错,我还推荐吗?) 4、关于安全性,我们经常听到eval是魔鬼,他会引起XSS攻击,实际上,如果我们对信息源有足够的把握时,eval并不会引起很大的安全问题。而且不光是eval,其他方式也可能引起安全问题。比如: 莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码… 所以啊,只要你的信息源不安全,你的代码就不安全。不单单是因为eval引起的。 你用eval的时候会在意XSS的问题,你越在意就越出问题,出的多了,eval就成噩梦了。 5、效率问题是程序逻辑问题。对于一些有执行字符串代码需求的程序中,不用eval而用其他方式模拟反而会带来更大的开销。eval 好不好取决于怎么使用它,一般认为的缺点:
1. 可读性非常差 2. 不好再做优化和编译 3. 会轻微增加性能消耗 4. 不安全,比如 eval input 的值考虑 eval 的时候认为所有的问题不用 eval 都可以解决的,比如给 obj.prop1, obj.prop2 …… 这序列赋值,可以 obj[prop + 'index'] = 'xxx' 。
然后确实不能解决问题的时候再用,其实 eval 也没那么烂,因为 ECMA 5 内置的 JSON.parse 内部也是用 eval,包括 jQuery 的 parseJSON 也用 eval。eval 用的好不好 其实和使用者的水平有关系
一般来讲,书上说叫你别用“eval”, 意思大概是说在座各位还没精通之前请先不要用eval“不要用” 这种说法主要是针对新手的 eval 很多情况下是用于解决一些一般代码中实现不了的效果1.比如,如何在 use strict 模式下函数作用域内获得全局this对象(window)
我们来看看doT中是怎么做的:( 什么? doT是什么你不知道?)var _globals = (function(){ return this || (0,eval)("this"); }());
2.又比如, 需要在 template 中动态编译 N 个参数时,eval 的作用就很明显了,可以动态生成函数所接受的形参,并且固定死名字, 请问 arguments 对象能做得到么?
当然如果你很想用 new Function.prototype.bind.apply 这种又长又臭的方法,我不拦着你啊.3. 不是有人吹要用老道的 < JavaScript The Good Part > 么? 那么你看看人家老道的JSON2是怎么写的?
// From JSON2.js
if (/^[\],:{}\s]*$/ .test(text.replace(/*regEx*/, '@') .replace(/*regEx*/, ']') .replace(/*regEx*/, ''))) { j = eval('(' + text + ')');} 4. jspref 上有很多测试已经证明了,各位麻烦多翻翻墙 , eval性能不是很低,eval 和 with 被人轻视的原因在于, 1. 网上的文章太多,干货太少,结论完全靠猜想 2. 对于eval 和 with 的理解还不够