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 相关文章推荐
jWiard 基于JQuery的强大的向导控件介绍
Oct 28 Javascript
JavaScript实现多维数组的方法
Nov 20 Javascript
JS中字符串trim()使用示例
May 26 Javascript
javascript 常见功能汇总
Jun 11 Javascript
H5基于iScroll实现下拉刷新和上拉加载更多
Jul 18 Javascript
vue页面使用阿里oss上传功能的实例(二)
Aug 09 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
Jan 23 Javascript
6行代码实现微信小程序页面返回顶部效果
Dec 28 Javascript
JavaScript函数式编程(Functional Programming)纯函数用法分析
May 22 Javascript
vue点击按钮动态创建与删除组件功能
Dec 29 Javascript
原生js实现瀑布流效果
Mar 09 Javascript
js实现九宫格布局效果
May 28 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
JQuery 表格操作(交替显示、拖动表格行、选择行等)
2009/07/29 Javascript
JavaScript内核之基本概念
2011/10/21 Javascript
js multiple全选与取消全选实现代码
2012/12/04 Javascript
阻止子元素继承父元素事件具体思路及实现
2013/05/02 Javascript
JS保留两位小数,多位小数的示例代码
2014/01/07 Javascript
js限制checkbox选中个数以限制六个为例
2014/07/15 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
JS中from 表单序列化提交的代码
2017/01/20 Javascript
EL表达式截取字符串的函数说明
2017/09/22 Javascript
实现单层json按照key字母顺序排序的示例
2017/12/06 Javascript
vuex提交state&amp;&amp;实时监听state数据的改变方法
2018/09/16 Javascript
在Vuex使用dispatch和commit来调用mutations的区别详解
2018/09/18 Javascript
vue过滤器用法实例分析
2019/03/15 Javascript
vue axios封装及API统一管理的方法
2019/04/18 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
深入理解 ES6中的 Reflect用法
2020/07/18 Javascript
利用Psyco提升Python运行速度
2014/12/24 Python
Python性能优化技巧
2015/03/09 Python
python中nan与inf转为特定数字方法示例
2017/05/11 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
python分布式环境下的限流器的示例
2017/10/26 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)
2018/10/11 Python
django admin后台添加导出excel功能示例代码
2019/05/15 Python
使用Filter过滤python中的日志输出的实现方法
2019/07/17 Python
pip install python 快速安装模块的教程图解
2019/10/08 Python
python模拟实现斗地主发牌
2020/01/07 Python
python中os包的用法
2020/06/01 Python
巧用CSS3 border实现图片遮罩效果代码
2012/04/09 HTML / CSS
办公室年终个人自我评价
2013/10/28 职场文书
我的动漫时代的创业计划书范文
2014/01/27 职场文书
暑期研修感言
2014/02/17 职场文书
五一劳动节活动总结
2015/02/09 职场文书
酒店辞职信怎么写
2015/02/27 职场文书
tensorboard 可视化之localhost:6006不显示的解决方案
2021/05/22 Python
Java Spring Boot 正确读取配置文件中的属性的值
2022/04/20 Java/Android