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 相关文章推荐
锋利的jQuery 第三章章节总结的例子
Mar 23 Javascript
javascript将数组插入到另一个数组中的代码
Jan 10 Javascript
onkeypress字符按键兼容所有浏览器使用介绍
Apr 24 Javascript
用javascript读取xml文件读取节点数据
Aug 12 Javascript
javascript抽象工厂模式详细说明
Dec 16 Javascript
JavaScript版的TwoQueues缓存模型
Dec 29 Javascript
JS实现的系统调色板完整实例
Dec 21 Javascript
js实现本地时间同步功能
Aug 26 Javascript
Parcel 打包示例(React HelloWorld)
Jan 16 Javascript
node.js中fs文件系统目录操作与文件信息操作
Feb 24 Javascript
Koa 使用小技巧(小结)
Oct 22 Javascript
一篇文章学会Vue中间件管道
Jun 20 Vue.js
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
全国FM电台频率大全 - 30 宁夏回族自治区
2020/03/11 无线电
PHP删除数组中的特定元素的代码
2012/06/28 PHP
php+mysql实现数据库随机重排实例
2014/10/17 PHP
php将数组转换成csv格式文件输出的方法
2015/03/14 PHP
PHP微信开发之二维码生成类
2015/06/26 PHP
php实现的Curl封装类Curl.class.php用法实例分析
2015/09/25 PHP
PHP面向对象详解(三)
2015/12/07 PHP
PHP封装的XML简单操作类完整实例
2017/11/13 PHP
不错的JS中变量相关的细节分析
2007/08/13 Javascript
Jquery中getJSON在asp.net中的使用说明
2011/03/10 Javascript
jquery 实现二级/三级/多级联动菜单的思路及代码
2013/04/08 Javascript
js倒计时小程序
2013/11/05 Javascript
$.each遍历对象、数组的属性值并进行处理
2014/07/18 Javascript
JavaScript代码轻松实现网页内容禁止复制(代码简单)
2015/10/23 Javascript
javascript闭包(Closure)用法实例简析
2015/11/30 Javascript
Three.js学习之正交投影照相机
2016/08/01 Javascript
js enter键激发事件实例代码
2016/08/17 Javascript
nodejs redis 发布订阅机制封装实现方法及实例代码
2016/12/15 NodeJs
性能优化之代码优化页面加载速度
2017/03/01 Javascript
一个可复用的vue分页组件
2017/05/15 Javascript
利用JS做网页特效_大图轮播(实例讲解)
2017/08/09 Javascript
jQuery的时间datetime控件在AngularJs中的使用实例(分享)
2017/08/17 jQuery
jQuery插件实现非常实用的tab栏切换功能【案例】
2019/02/18 jQuery
使用js在layui中实现上传图片压缩
2019/06/18 Javascript
Nodejs + Websocket 指定发送及群聊的实现
2020/01/09 NodeJs
js实现微信聊天界面
2020/08/09 Javascript
python 读取文件并替换字段的实例
2018/07/12 Python
python实现小程序推送页面收录脚本
2020/04/20 Python
Oroton中国官网:澳洲知名奢侈配饰品牌
2017/03/26 全球购物
工商管理专业学生的自我评价
2013/10/01 职场文书
宿舍标语大全
2014/06/19 职场文书
2015大学生自我评价范文
2015/03/03 职场文书
2015年小学数学教研组工作总结
2015/05/21 职场文书
《抽屉原理》教学反思
2016/02/20 职场文书
2016年小学中秋节活动总结
2016/04/05 职场文书
php png失真的原因及解决办法
2021/11/17 PHP