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学习笔记之jQuery的DOM操作
Dec 22 Javascript
javascript打印大全(打印页面设置/打印预览代码)
Mar 29 Javascript
可恶的ie8提示缺少id未定义
Mar 20 Javascript
分享一则javascript 调试技巧
Jan 02 Javascript
js实现进度条的方法
Feb 13 Javascript
JavaScript中textRange对象使用方法小结
Mar 24 Javascript
JavaScript 冒泡排序和选择排序的实现代码
Sep 03 Javascript
BootStrap 模态框实现刷新网页并关闭功能
Jan 04 Javascript
html5+canvas实现支持触屏的签名插件教程
May 08 Javascript
angular2系列之路由转场动画的示例代码
Nov 09 Javascript
基于js中style.width与offsetWidth的区别(详解)
Nov 12 Javascript
vue  directive定义全局和局部指令及指令简写
Nov 20 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不用内置函数对数组排序的两个算法代码
2010/02/08 PHP
zf框架的zend_cache缓存使用方法(zend框架)
2014/03/14 PHP
php实现的中秋博饼游戏之掷骰子并输出结果功能详解
2017/11/06 PHP
Laravel使用消息队列需要注意的一些问题
2017/12/13 PHP
Thinkphp 5.0实现微信企业付款到零钱
2018/09/30 PHP
浅析IE10兼容性问题(frameset的cols属性)
2014/01/03 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
AspNet中使用JQuery boxy插件的确认框
2015/05/20 Javascript
JavaScript中几种排序算法的简单实现
2015/07/29 Javascript
全面解析Bootstrap手风琴效果
2020/04/17 Javascript
JavaScript获取服务器端时间的方法
2016/11/29 Javascript
ionic 3.0+ 项目搭建运行环境的教程
2017/08/09 Javascript
jquery对table做排序操作的实例演示
2017/08/10 jQuery
vue Element-ui input 远程搜索与修改建议显示模版的示例代码
2017/10/19 Javascript
JS使用setInterval实现的简单计时器功能示例
2018/04/19 Javascript
Vue使用NProgress进度条的方法
2019/09/21 Javascript
Vue实现仿iPhone悬浮球的示例代码
2020/03/13 Javascript
vue data有值,但是页面{{}} 取不到值的解决
2020/11/09 Javascript
python清除字符串里非数字字符的方法
2015/07/02 Python
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
Python OpenCV获取视频的方法
2018/02/28 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
详解pytorch 0.4.0迁移指南
2019/06/16 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
2020/02/03 Python
安装python3.7编译器后如何正确安装opnecv的方法详解
2020/06/16 Python
python交互模式基础知识点学习
2020/06/18 Python
基于Python爬取京东双十一商品价格曲线
2020/10/23 Python
英国国家美术馆商店:National Gallery
2019/05/01 全球购物
美国在线面料商店:Fashion Fabrics Club
2020/01/31 全球购物
如何利用find命令查找文件
2016/11/18 面试题
爱岗敬业演讲稿范文
2014/01/14 职场文书
职工运动会邀请函
2014/01/19 职场文书
2014迎国庆演讲稿
2014/09/19 职场文书
2014年艾滋病防治工作总结
2014/12/10 职场文书