Javascript学习笔记4 Eval函数


Posted in Javascript onJanuary 11, 2010

eval的作用其实很简单,就是把一段字符串传递给JS解释器,由Javascript解释器将这段字符串解释成Javascript代码,并且执行他。
举个最简单的例子:

<script type="text/javascript"> 
eval("alert(1+1)"); 
</script>

很简单,把字符串解释成JS代码并执行,弹出2。
当然,上面的例子只是个玩具,在实际中没有人会傻到这么用。我想大家最基本的使用eval函数都是应该在DOM中,例如我们有div1,div2,div3,那么在document.getElementByID时我们的ID没有办法去得到,那么最简单的办法就是在for循环中,使用eval来拼接这么一段程序。例如这样:
<script type="text/javascript"> 
for (var loop = 1; loop < 10; loop++) { 
eval('document.getElementById("div"+loop).innerHTML="123"'); 
} 
</script>

最基本的用法说完,相信大家还是对这个函数意犹未尽,如果这个函数只有这么点用法,那就太无聊了。那我们就一点点来剖下一下eval()函数。
我们就先从eval的作用域说起,先看这样一段函数:
<script type="text/javascript"> 
eval("var i=3"); 
alert(i); 
</script>

代码很简单,结果可以弹出3。接下来再对比这段代码:
<script type="text/javascript"> 
var test = function () { 
eval("var i=3"); 
alert(i); 
} 
test(); 
alert(i); 
</script>

结果是首先弹出3,然后是undefined。
那么说明:eval()函数动态执行的代码并不会创建新的作用域,其代码就是在当前的作用域执行的。因此也就是说,eval()函数也完全可以使用当前作用域的this,argument等对象。
在IE中,支持这样一种和eval()非常类似的函数叫做:execScript()。我们可以来写段简单的代码。
<script type="text/javascript"> 
var test = function () { 
execScript("var i=3"); 
alert(i); 
} 
test(); 
alert(i); 
</script>

结果弹出了2个3,这也就看出了execScript函数的特点,首先他和eval相类似,都能将字符串解释成JS代码并且执行,但是他的作用域不是当前作用域,而是全局作用域。当我们把上面的代码放到Firefox和谷歌浏览器上去试试:发现在Firefox上execScript上代码是无效的,那么也说明一个问题,execScript代码的浏览器兼容性是有问题的。
那么就引申出这样一个问题,我们如何能把这两个函数的“优点”给汇总到一起呢,也就是说,全局+浏览器兼容性。上网搜了下,自己给汇总了一下,大概是这样:
<script type="text/javascript"> 
var StrongEval = function (code) { 
if (window.navigator.userAgent.indexOf("MSIE") >= 1) { 
execScript(code); 
} 
if (window.navigator.userAgent.indexOf("Firefox") >= 1) { 
window.eval(code); 
} 
else { 
execScript(code); 
} 
}; 
var Test = function () { 
StrongEval("var i=3"); 
} 
Test(); 
alert(i); 
</script>

这样就可以完美地兼容FF和IE了,其本质代码就在于在FF中eval和window.eval并不等效,这是个很奇妙的事。
另外,我们还可以用eval+with实现一些奇淫技巧。
我们在一般意义上可以写出这样的代码:
var obj = function () { 
this.a = 1; 
this.b = 2; 
this.c = 5; 
this.fun = function () { 
this.c = this.a + this.b; 
} 
}; 
var o = new obj(); 
o.fun(); 
alert(o.c);

或者是这样:
var obj = { 
a: 1, 
b: 2, 
c: 5, 
fun: function () { 
this.c = this.a + this.b; 
} 
}

再或者是这样:
var obj = function () { 
this.a = 1; 
this.b = 2; 
this.c = 5; 
}; 
obj.prototype.fun = function () { 
this.c = this.a + this.b; 
} 
var o = new obj(); 
o.fun(); 
alert(o.c);

无论怎么样,你是不是对这样的this感觉厌烦了呢?那就让我们采取个很另类的办法吧,让至少在感官上可能会舒服一点。
<script type="text/javascript"> 
var funtemp = function () { 
c = a + b; 
} 
var obj = { 
a: 1, 
b: 2, 
c: 5 
}; 
var fun; 
with (obj) { 
eval("fun = " + funtemp); 
} 
fun(); 
alert(obj.c); 
</script>

这个很勉强,那么好,我们不讨论什么看着舒服不舒服。我们来讨论这样一种情况。
<script> 
var DBCommon = function () { 
alert("1."); CreateConnection(); 
alert("2."); OpenConnection(); 
alert("3."); CreateCommand(); 
alert("4."); ExcuteCommand(); 
alert("5."); CloseConnection(); 
} 
var SQLServerCommon = { 
CreateConnection: function () { alert("建立SQL Server连接"); }, 
OpenConnection: function () { alert("打开SQL Server连接"); }, 
CreateCommand: function () { alert("创建¨SQL Server命令"); }, 
ExcuteCommand: function () { alert("执行DSQL Server命令"); }, 
CloseConnection: function () { alert("关闭SQL Server连接"); } 
}; 
var OracleCommon = { 
CreateConnection: function () { alert("建立¢Oracle连接"); }, 
OpenConnection: function () { alert("打开aOracle连接"); }, 
CreateCommand: function () { alert("创建¨Oracle命令"); }, 
ExcuteCommand: function () { alert("执行DOracle命令"); }, 
CloseConnection: function () { alert("关闭?Oracle连接"); } 
}; 
with (SQLServerCommon) { 
eval("forSQLServer=" + DBCommon); 
} 
with (OracleCommon) { 
eval("forOracle=" + DBCommon); 
} 
forSQLServer(); 
forOracle(); 
</script>

我们又是否可以把这个看成是一个简陋的模板方法模式呢?呵呵。我们也可以把这个称为利用eval和with配合改变函数的上下文。
不过话又说回来,Eval在一般的情况中是很少被用到的,我们是完全可以避免来使用它的。
Javascript 相关文章推荐
javaScript(JS)替换节点实现思路介绍
Apr 17 Javascript
基于JavaScript 声明全局变量的三种方式详解
May 07 Javascript
怎么清空javascript数组
May 11 Javascript
jquery实现兼容浏览器的图片上传本地预览功能
Oct 14 Javascript
javascript获取xml节点的最大值(实现代码)
Dec 11 Javascript
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
May 20 Javascript
21个JavaScript事件(Events)属性汇总
Dec 02 Javascript
JS非Alert实现网页右下角“未读信息”效果弹窗
Sep 26 Javascript
Jquery操作cookie记住用户名
Mar 29 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
Jun 22 Javascript
Vue侦测相关api的实现方法
May 22 Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
Apr 27 Javascript
Javascript学习笔记2 函数
Jan 11 #Javascript
Javascript学习笔记1 数据类型
Jan 11 #Javascript
IE bug table元素的innerHTML
Jan 11 #Javascript
javascript instanceof 与typeof使用说明
Jan 11 #Javascript
javascript call方法使用说明
Jan 11 #Javascript
jQuery UI-Draggable 参数集合
Jan 10 #Javascript
将CKfinder整合进CKEditor3.0的新方法
Jan 10 #Javascript
You might like
PHP自动识别字符集并完成转码详解
2013/08/02 PHP
php使用PDO方法详解
2014/12/27 PHP
Laravel使用scout集成elasticsearch做全文搜索的实现方法
2018/11/30 PHP
asp.net下利用js实现返回上一页的实现方法小集
2009/11/24 Javascript
jQuery插件 tabBox实现代码
2010/02/09 Javascript
javascript阻止scroll事件多次执行的思路及实现
2013/11/08 Javascript
JavaScript避免代码的重复执行经验技巧分享
2014/04/17 Javascript
jQuery实现倒计时按钮功能代码分享
2014/09/03 Javascript
jquery单击事件和双击事件冲突解决方案
2016/03/02 Javascript
json数据处理及数据绑定
2017/01/25 Javascript
jquery横向纵向鼠标滚轮全屏切换
2017/02/27 Javascript
Bootstrap table使用方法总结
2017/05/10 Javascript
网页中的图片查看器viewjs使用方法
2017/07/11 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
2019/11/04 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
javascript实现简单留言板案例
2021/02/09 Javascript
在Python的列表中利用remove()方法删除元素的教程
2015/05/21 Python
在Python程序中操作文件之isatty()方法的使用教程
2015/05/24 Python
Python中的错误和异常处理简单操作示例【try-except用法】
2017/07/25 Python
如何用Python实现简单的Markdown转换器
2018/07/16 Python
Python学习笔记之pandas索引列、过滤、分组、求和功能示例
2019/06/03 Python
基于python-opencv3的图像显示和保存操作
2019/06/27 Python
Python_查看sqlite3表结构,查询语句的示例代码
2019/07/17 Python
在Django下测试与调试REST API的方法详解
2019/08/29 Python
Django Admin设置应用程序及模型顺序方法详解
2020/04/01 Python
Django分组聚合查询实例分享
2020/04/29 Python
html5如何及时更新缓存文件(js、css或图片)
2013/06/24 HTML / CSS
银行会计财务工作个人的自我评价
2013/10/29 职场文书
童装店创业计划书
2014/01/09 职场文书
创新型城市实施方案
2014/03/06 职场文书
党的群众路线教育实践活动督导组工作情况汇报
2014/10/28 职场文书
2014年监理工作总结范文
2014/11/17 职场文书
2014年度考核工作总结
2014/12/24 职场文书
2015年专项整治工作总结
2015/04/03 职场文书
残联2016年全国助残日活动总结
2016/04/01 职场文书
python垃圾回收机制原理分析
2022/04/13 Python