读书人

遗弃eval吧

发布时间: 2013-06-26 14:29:32 作者: rapoo

抛弃eval吧。
刚看了这篇帖子 eval 获得对象用法 请教达人 有点感想,发上来供大家参考。

eval在javascript语言精粹中被作者归为js的鸡肋特性之一,刚温习了下本书,下面是该书对eval的描述:

eval函数传递一个字符串给javascript编译器,并且执行其结果。它是一个被滥用得最多的javascript特性。那些对javascript语言一知半解的人们最常用到它。例如:如果你知道点表示法,但不知道下标表示法,就可能会这么写:

eval("myValue = myObject." + myKey + ";");


而不是这么写:

myValue = myObject[myKey];


使用eval形式的代码会更加难以阅读。这种形式将使得性能显著降低,因为它必须运行编译器,但也许只是为了执行一个微不足道的赋值语句。它会让JSLint失效,因此该工具检测问题的能力也会显著降低。

eval函数还减弱了你的应用的安全性,因为它给被求值的文本赋予了太多的权力。而且就像with语句执行的方式一样,它降低了语言的性能。

Function构造器是eval的另一种形式,所以它同样也应该被避免使用。

浏览器提供的setTimeout和setInterval函数,它们能接收字符串参数或函数参数。

当传递的是字符串参数时,setTimeout和setInterval会像eval那样去处理。字符串参数形式也应该被避免使用。



个人在开发中没有碰到过必须用eval的时候,都可以用别的形式替换,所以让我们抛弃eval吧。

[解决办法]
可以选择不用
[解决办法]
ActionScript 3.0自认为可以抛弃eval,于是...D.eval。


[解决办法]
ajax怎么处理扔过来的js呢?
[解决办法]
不能因为难以阅读,而抛弃它吧?这个理由好像不太合适
eval() 的功能虽然非常强大,但大家都知道在实际使用中用到它的情况并不多
所以根据实际情况选择!
[解决办法]
不用算了。
[解决办法]
我不是很赞同楼主的观点;如果抛弃了eval;我不知道如何处理JOSN数据信息;同时如果没有setTimeout和setInterval,呵呵;你的前端特效该如何做?同时楼主并没有说清楚不用eval的好处和使用eval的坏处,可见楼主对这方面的认识也是人云亦云罢了;
[解决办法]
我很少去使用它,但有时候真的不用它解决起来麻烦的很

尤其是ajax要去跑返回的js代码的时候

也许,大多数情况你都可以很轻易的使用其它方式避免使用eval,但有时候的确还是用eval更方便一些

所以个人觉得,还是根据实际情况选择是否使用eval的好

存在,即合理
[解决办法]
顶7楼
存在即合理,因为有需求。
[解决办法]
<script>
var a=1, b=2, ret=false;ret=a+b; alert(ret);
//-------------------------

假设数据库中存储了上面那段运行代码;从数据库中取出后得到字串:
var str="var a=1, b=2, ret=false;ret=a+b; alert('想办法让这个ALERT跳出来:'+ret);"
eval(str)//用eval(),轻而易举;

xxxyyyzzz...$#%^: //不用eval(),楼主有更好的方法没?


</script>
[解决办法]
顶七楼!
我一般都是用eval绑定一个ajax返回的json对象,数组之类的
[解决办法]
引用:
ajax怎么处理扔过来的js呢?

lz 都说了可以用new Function


[解决办法]
高手
[解决办法]
引用:
引用:
ajax怎么处理扔过来的js呢?

lz 都说了可以用new Function

JScript code
var c = new Function('return {a:"b"}')();
alert(c.a);


ps 之前看qwrap很多 new Function 今天搜索了一下 一个eval都没有


http://w……


这个东西挺有趣,看一下
[解决办法]
纯属标题党...

毫无意义的问题
[解决办法]
引用:
……
eval函数还减弱了你的应用的安全性,因为它给被求值的文本赋予了太多的权力。而且就像with语句执行的方式一样,它降低了语言的性能。

Function构造器是eval的另一种形式,所以它同样也应该被避免使用。

浏览器提供的setTimeout和setInterval函数,它们能接收字符串参数或函数参数。

当传递的是字符串参数时,setTimeout和setInterval会像eval那样去处理。字符串参数形式也应该被避免使用。
……

天哪。eval不用,Function不用,setTimeout和setInterval也不用。我们还能用什么?
[解决办法]
呵呵。。我是新手,发觉这个问题很有趣啊。。。我刚做完一个项目,页面的多个按钮对表单进行提交时,我为了编码的重用,传了表单的name:eval("document."+name).action="";这样有什么弊端吗???
请教大家。。谢谢指导。。

[解决办法]
引用:
纯属标题党...

毫无意义的问题

毫无意义????why???
[解决办法]
引用:
引用:
纯属标题党...

毫无意义的问题

毫无意义????why???


存在即合理,

如果是高手树叶都能杀人.

主要是看用的人,怎么用. 跟用的武器有什么关系
[解决办法]
实践下来可以比较负责的说
除了json字符串转object外 确实可以不用eval
[解决办法]
从QWrap逆流来这里,原来有同学在CSDN里提到QWrap。。。
几个月前在CSDN发过一个宣传QWrap的贴子,可惜被当广告删掉了,便放弃在CSDN宣传QWrap。。。。
叹一声:N年前还曾当过两年这个版的版主,现在几乎找不到熟识的人啊。

eval除了有效率问题,还有可能因为其字符串参数中的具体内容改变作用域链上的变量,这增加了代码的不确定性、降低了代码的可读性、还会导致变量名不被压缩(保守压缩)等等。
new Function的外层作用域是在window上的,所以可以不影响压缩与作用域链。。。
[解决办法]
实在是惭愧,,很多时候除了eval外,不知道其他方法
[解决办法]
请问ajax如何很后台传json到前台?后台拼完字符串之后用eval很不错哦。





--------------------------------------帅签分割线-------------------------------------------------
遗弃eval吧
[解决办法]

引用:
这样的js代码字符确实只能用eval执行了,个人觉得有更好的方式处理为什么不用呢? 完全可以后端的逻辑处理好后,在传到前端啊。 不然直接传到前端处理也可以。为什么一定要后端写好js语句,再传到前端执行呢?

你的辩才还真不错。看这个例子:
<script runat=server>
var a=1, b=2, ret=false;ret=a+b; response.write(ret);
//-------------------------

//假设数据库中存储了上面那段运行代码;从数据库中取出后得到字串:
var str="var a=1, b=2, ret=false;ret=a+b; response.write('想办法打印计算结果:'+ret);"
eval(str)//用eval(),轻而易举;

xxxyyyzzz...$#%^: //不用eval(),楼主有更好的方法没?
</script>
数据库中保存计算公式也是常有的事
[解决办法]
刚好,最近遇到一个问题,大家有啥好的解决办法不?

chatUI={};
chatUI.emot=[ //表情列表 ["图片名","Encode时的替换字符","Decode时Replace的RegEx"]
["angry.png",">:o",/>:o/gi],
["blush.png",":-[",/:-\[/gi],
["confused.png","?:
[解决办法]
",/\?:\
[解决办法]
/gi],
["cool.png","B-)",/B-\)/gi],
["cry.png",":'(",/:'\(/gi],
["devil.png","]:)",/\]:\)/gi],
["grin.png",":-D",/:-D/gi],
["happy.png",":-)",/:-\)/gi],
["laugh.png",":^0",/:\^0/gi],
["love.png",":x",/:x/gi],
["mischief.png",";\\",/;\\/gi],
["sad.png",":-(",/:-\(/gi],
["silly.png",":-p",/:-p/gi],
["wink.png",";-)",/;-\)/gi]
]
chatUI.emotFolder="images/chat/emot1/"; //表情图像存放文件夹
//-----------------
chatUI.msgEncode=function(str){ //将html 编码成传送用的字符 @string @return string
if(str=="")return str;
var that=this;
var r='';
/*链接(提取a href的值)*/
str=str.replace(/\<a.*\s*href=(['
[解决办法]
"]*)([\w?#=.:;&%/\u4e00-\u9fa5]*)\1\s*.*\>.*\<\/a\>/gi,"$2");
/*表情*/
var emot=[];
for(var k=0;k<that.emot.length;k++){
emot[k]=that.emot[k][0];
}
var regstr='var reg=/<img.*\\s*src\\s*=\\s*.*(["
[解决办法]
\']*)'+that.emotFolder.split("/").join("\\/")+'('+emot.join("
[解决办法]
")+')\\1\\s?.*>/';
eval(regstr);
str=str.replace( reg,
function($1,$2,$3){
for(var k=0;k<that.emot.length;k++){
if($3==that.emot[k][0]){
return that.emot[k][1];
}
}
});
/*图像(提取img src的值)*/
//str=str.replace(/\<img.*\s*src=(['
[解决办法]
"]*)([\w?#=.:;&%/\u4e00-\u9fa5]*)\1\s*.*\>/gi,"$2");
/*HTML标签*/
//str=str.replace(/&/gi,"%26");
//str=str.replace(/\</gi,"<");
//str=str.replace(/\>/gi,">");
//str=str.replace(/=/gi,"%3D");
//str=str.replace(/\<br\s*\/?\>/gi,'<br />');
str=encodeURIComponent(str);
return str;
}


[解决办法]
艹,不能编辑啊,我上面有一个正则用的是eval,表情那部分

大概是要有个数组

[
["aa","11"],
["bb","22"],
["cc","33"]

]



要将字符串中的aa替换成 11,bb换成22,cc换成33。

JS半路出家,大家帮帮看,有其他啥办法。
[解决办法]
google 对eval的说明
[解决办法]
很少在用
[解决办法]
抛弃eval==抛弃javascript
[解决办法]

引用:
从QWrap逆流来这里,原来有同学在CSDN里提到QWrap。。。
几个月前在CSDN发过一个宣传QWrap的贴子,可惜被当广告删掉了,便放弃在CSDN宣传QWrap。。。。
叹一声:N年前还曾当过两年这个版的版主,现在几乎找不到熟识的人啊。

eval除了有效率问题,还有可能因为其字符串参数中的具体内容改变作用域链上的变量,这增加了代码的不确定性、降低了代码的可读性、还会导致变量名不被压……

我很顶这位老兄的看法
但是除json转object外
[解决办法]
打个不恰当的比喻,eval就像核能,安全的使用是可以的,乱用才会后果严重,但是不能因为害怕危险就抛弃它吧。
[解决办法]
引用:
引用:
这样的js代码字符确实只能用eval执行了,个人觉得有更好的方式处理为什么不用呢? 完全可以后端的逻辑处理好后,在传到前端啊。 不然直接传到前端处理也可以。为什么一定要后端写好js语句,再传到前端执行呢?

你的辩才还真不错。看这个例子:
<script runat=server>
var a=1, b=2, ret=false;ret=a……

不用eval,可以用new Function
var str="var a=1, b=2, ret=false;ret=a+b; document.write('想办法打印计算结果:'+ret);";
new Function(str)();

[解决办法]
引用:
引用:
ajax怎么处理扔过来的js呢?

lz 都说了可以用new Function


JScript code
var c = new Function('return {a:"b"}')();
alert(c.a);


ps 之前看qwrap很多 new Function 今天搜索了一下 一个eval都没有


http://……

new Function如果是这样用,简直就是脱裤子放屁,直观感觉让程序逻辑更复杂了
[解决办法]
引用:
引用:
从QWrap逆流来这里,原来有同学在CSDN里提到QWrap。。。
几个月前在CSDN发过一个宣传QWrap的贴子,可惜被当广告删掉了,便放弃在CSDN宣传QWrap。。。。
叹一声:N年前还曾当过两年这个版的版主,现在几乎找不到熟识的人啊。

eval除了有效率问题,还有可能因为其字符串参数中的具体内容改变作用域链上的变量,这增加了代码的不确……

我很顶这位老兄的看法
但是除json转object外

json转object同样可以不用eval,可以利用new Function耍个小花招就可以了。
var json="{a:'1',b:2}";
var jsonobj=new Function('return '+json)();
alert(jsonobj.a+' and '+jsonobj.b);

很简单的小花招,而且还可以防止全局变量冲突。
[解决办法]
引用:
eval除了有效率问题,还有可能因为其字符串参数中的具体内容改变作用域链上的变量,这增加了代码的不确定性、降低了代码的可读性、还会导致变量名不被压缩(保守压缩)等等。
new Function的外层作用域是在window上的,所以可以不影响压缩与作用域链。。。

请举例说明:可用new Function却无法用eval。
倒想看看是使用者的问题,还是eval的问题
[解决办法]
引用:
很简单的小花招,而且还可以防止全局变量冲突。

var json="{a:'1',b:2}";
var jsonobj=eval(json);
alert(jsonobj.a+' and '+jsonobj.b);

这样写会有new Function中不存在的全局变量冲突问题?
[解决办法]
引用:
引用:
很简单的小花招,而且还可以防止全局变量冲突。

JScript code
var json="{a:'1',b:2}";
var jsonobj=eval(json);


alert(jsonobj.a+' and '+jsonobj.b);

这样写会有new Function中不存在的全局变量冲突问题?


不好意思,刚才是突然想到的,没有全局变量冲突应该是我上个帖子里的内容才对,就是后台传送js脚本来执行,如果直接用eval执行,若存在重名变量,就会覆盖以前的定义,造成数据不确定,但如果放在new Function里执行就是闭包了,不影响外部作用域的变量。像JSON这种数据,本身就是闭包,更不存在冲突了。
[解决办法]
再贴一遍:"eval除了有效率问题,还有可能因为其字符串参数中的具体内容改变作用域链上的变量,这增加了代码的不确定性、降低了代码的可读性、还会导致变量名不被压缩……"
------------------
至于eval(jsonStr),在保守的yui压缩下,也会导致作用域链上的变量名不被压缩。44楼loadown同学已有过回复。
QWrap的StringH中提供了一个方法,来解决这个作用域影响的问题:
/**
* eval某字符串,这个字符串是一个js表达式,并返回表达式运行的结果
* @method evalExp
* @static
* @param {String} s 字符串
* @param {any} opts eval时需要的参数。
* @return {any} 根据字符结果进行返回。
*/
evalExp: function(s, opts) {
return new Function("opts", "return (" + s + ");")(opts);
}
在实际项目中可以这样用:
var json="{a:'1',b:2}".evalExp();//不带参数用法
var json="{a:'1',b:opts.name}".evalExp({name:'JK'});//带参数用法
具体参见:
http://dev.qwrap.com/resource/js/_docs/_jk/?content=http://dev.qwrap.com/resource/js/_docs/_jk/qw/stringh/s.evalExp_.htm


[解决办法]
to 47楼loadown:"但如果放在new Function里执行就是闭包了"----或许你对闭包的理解有误。。。new Function的外层作用域是根作用域,所以,new Function不是通常所说的闭包。不过,如果理解所有的function都是闭包的这个“泛”概念的话,也说得过过,只是不适合47楼的语境(后面跟句“不影响外部作用域的变量”)。
[解决办法]
引用:
to 47楼loadown:"但如果放在new Function里执行就是闭包了"----或许你对闭包的理解有误。。。new Function的外层作用域是根作用域,所以,new Function不是通常所说的闭包。不过,如果理解所有的function都是闭包的这个“泛”概念的话,也说得过过,只是不适合47楼的语境(后面跟句“不影响外部作用域的变量”)。

不好意思,是我表述不完整,一般我们说全局变量冲突,经常是指当我们在最外层作用域定义一个变量时,如果该变量已被定义过,则会被新定义的重名变量覆盖掉,从而造成对原有变量引用时的不确定,严重时导致程序逻辑错误。那句“不影响外部作用域的变量”是个很有歧义的句子,我没说清楚是定义变量时不会产生冲突,因为在一个小的作用域里,定义变量,即使重名也不会覆盖上层作用域的同名变量,我在这里表述的“影响”实际是“冲突”的意思,不是不能改变外部作用域变量的意思。
[解决办法]
可能楼主可能还没涉及到某些eval很必要的地方,但是并不代表eval就会如此差,eval在某些时候也是必须用到的,比如声明某些可变的对象或方法的时候,目前我还不知道还有没有其他的方法能够实现。楼主是javascript高手?还没听说过哪位要放弃过eval的说法呢!要放弃官方早就放弃了
[解决办法]
引用:
再贴一遍:"eval除了有效率问题,还有可能因为其字符串参数中的具体内容改变作用域链上的变量,这增加了代码的不确定性、降低了代码的可读性、还会导致变量名不被压缩……"
------------------
至于eval(jsonStr),在保守的yui压缩下,也会导致作用域链上的变量名不被压缩。44楼loadown同学已有过回复。
QWrap的StringH中提供了一个方法,来解决这个作用域……

eval有效率、降低了代码的可读性,new Function不是存在同样的问题吗?
eval作用域为当前域,需要不影响当前域时,写个函数包装一下也很简单啊。压缩的问题也不存在了。
[解决办法]
对于表达式,eval的执行效率要高于new Function的方案,因为'return ('+Value+');'这个语句需要多拼接两次字符串
[解决办法]
另外,eval有时候是不能被new Function替换的,比如
var s='var a=1,b=2,c=a+b;c';
var v=eval(s);

你能写成下面这样吗?
var s='var a=1,b=2,c=a+b;c';
var v=(new Function('return ('+s+');'))();


[解决办法]
从效率来说,同等代码下,eval的效率应该高一些,而且eval的自由度更高,可以执行任意合法表达式;而new Function是有限制的,其表达式必须符合function的定义格式,所以要想让代码难读难懂还是离不开eval的,因为eval的执行字符串,只要合法可以千变万化,而new Function的执行字符串就要有规律的多了,从代码保密角度来讲还是eval更有保密性。
[解决办法]

引用:

从效率来说,同等代码下,eval的效率应该高一些,而且eval的自由度更高,可以执行任意合法表达式;而new Function是有限制的,其表达式必须符合function的定义格式,所以要想让代码难读难懂还是离不开eval的,因为eval的执行字符串,只要合法可以千变万化,而new Function的执行字符串就要有规律的多了,从代码保密角度来讲还是eval更有保密性。

但是eval完全可以替代new Function,只不过使用起来更为灵活与强大。
代码难读难懂与eval无关,关键是写代码的人。
[解决办法]
引用:
ajax怎么处理扔过来的js呢?

(new Function('js字符串'))()
[解决办法]
引用:
从效率来说,同等代码下,eval的效率应该高一些,而且eval的自由度更高,可以执行任意合法表达式;而new Function是有限制的,其表达式必须符合function的定义格式,所以要想让代码难读难懂还是离不开eval的,因为eval的执行字符串,只要合法可以千变万化,而new Function的执行字符串就要有规律的多了,从代码保密角度来讲还是eval更有保密性。

可以把eval当成new Function用,很简单的包一下就可以了。
代码难读难懂怎么能怪eval呢?
那如果你用到new Function实现某些东西相对于eval要麻烦很多的时候,你又会怪谁呢?
[解决办法]
少用eval,Function之流显然是有好处的,代码风格更规范,更易于调试
[解决办法]
引用:
少用eval,Function之流显然是有好处的,代码风格更规范,更易于调试

少用与抛弃是两回事,楼主的标题过了点
[解决办法]
最锋利的剑也是最难驾驭的。
[解决办法]
evel 是什么东西来的!!TMD ,现在太多东西要学了
[解决办法]
存在即合理!!
[解决办法]
代码难读难懂怎么能怪eval呢?
[解决办法]
学习啦~~~
[解决办法]
存在即合理
[解决办法]
存在即合理
[解决办法]
围观下 觉得还行的
[解决办法]
以为是eva~~~~
[解决办法]
就没用过,何来抛弃。。。
[解决办法]
该回复于2012-04-03 11:04:50被版主删除
[解决办法]
晕,这么好的东西不用?

楼主在早期有用过 FoxPro 没有?

这个有点类似 FoxPro 的宏替换,当年我们的老师也都是教大家不要用宏替换,但在实际的应用中,不用宏替换会走多少弯路?而且有些弯路不用宏替换还真的弯不过去

[解决办法]
学习了撒
[解决办法]
根据实际情况选择是否使用eval的好.
[解决办法]
eval在javascript语言精粹中被作者归为js的鸡肋特性之
[解决办法]
引用:
eval在javascript语言精粹中被作者归为js的鸡肋特性之

我想作者写过的都是一些常规程序,没有碰到过只有用eval才能方便快捷的解决问题的情况,所以才会这样说。
说实话,一般的网站程序,除了json数据解析必须需要用到eval(不用难道自己写序列化与反序列化程序?),都可以不用eval或者new Function之类的动态代码。
如果你做一个类似excel的公式计算功能的时候,你认为是自己写个语法分析器好,还是用eval实现更好?
如果你做一个与数据无关的操作过程的保存,过程的每个步骤都是一条语句代码,你是自己分拆再组装代码,还是用eval实现更好?
如果你的ajax应用做一个模拟历史记录的功能,也就是把程序状态序列化HTML代码中,你是自己写序列化与反序列化程序好,还是用eval实现更好?
以上这些都是我能想到或实际经历的,至少我认为没有比eval更好更优雅的解决方案了。当然应该还有一些其它应用也会类似,只是我没有碰到过而已。



作者因为自己没有用到,或者用到的少就说是鸡肋特性,如果没有合情的理由支持,是不负责的说法。
[解决办法]
我也觉得存在即合理,有时用Eval做ajax等数据绑定的时候满给力的!
[解决办法]

引用:
引用:
ajax怎么处理扔过来的js呢?

lz 都说了可以用new Function


JScript code
var c = new Function('return {a:"b"}')();
alert(c.a);


ps 之前看qwrap很多 new Function 今天搜索了一下 一个eval都没有


http://……

那又如何知道那个“a”呢?
[解决办法]
该回复于2011-06-07 09:06:21被版主删除
[解决办法]
理好你的json,可以避免使用eval,竟eval的效率不咋滴。
[解决办法]
该回复于2011-06-07 09:16:56被版主删除
[解决办法]
引用:
理好你的json,可以避免使用eval,竟eval的效率不咋滴。

有一串的疑问:必竟服务器返回的只是字符串,难道你不用把字符串解析成对象?难道你自己写解析函数?难道你的解析函数比eval效率更高?

读书人网 >JavaScript

热点推荐