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 相关文章推荐
使用onbeforeunload属性后的副作用
Mar 08 Javascript
JavaScript 学习笔记(九)call和apply方法
Jan 11 Javascript
javascript之AJAX框架使用说明
Apr 24 Javascript
ExtJS中文乱码之GBK格式编码解决方案及代码
Jan 20 Javascript
Ajax异步提交表单数据的说明及方法实例
Jun 22 Javascript
jquery 设置元素相对于另一个元素的top值(实例代码)
Nov 06 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
Mar 01 Javascript
使用纯JS代码判断字符串中有多少汉字的实现方法(超简单实用)
Nov 12 Javascript
p5.js入门教程和基本形状绘制
Mar 15 Javascript
PHP实现基于Redis的MessageQueue队列封装操作示例
Feb 02 Javascript
一些你可能不熟悉的JS知识点总结
Mar 15 Javascript
vuex页面刷新导致数据丢失的解决方案
Dec 10 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
淘宝ip地址查询类分享(利用淘宝ip库)
2014/01/07 PHP
PHP借助phpmailer发送邮件
2015/05/11 PHP
Javascript操纵Cookie实现购物车程序
2007/02/15 Javascript
jQuery Ajax之load()方法
2009/10/12 Javascript
JavaScript Math.floor方法(对数值向下取整)
2015/01/09 Javascript
聊一聊jQuery插件uploadify使用方法
2016/08/24 Javascript
Angular路由简单学习
2016/12/26 Javascript
分享十三个最佳JavaScript数据网格库
2017/04/07 Javascript
利用require.js与angular搭建spa应用的方法实例
2017/07/19 Javascript
自适应布局meta标签中viewport、content、width、initial-scale、minimum-scale、maximum-scale总结
2017/08/18 Javascript
在Vue组件化中利用axios处理ajax请求的使用方法
2017/08/25 Javascript
小程序实现左滑删除功能
2018/10/30 Javascript
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
JavaScript中0、空字符串、'0'是true还是false的知识点分享
2019/09/16 Javascript
[00:59]DOTA2荣耀之路1:Doom is back!weapon X!
2018/05/22 DOTA
Python实现对比不同字体中的同一字符的显示效果
2015/04/23 Python
Python3如何解决字符编码问题详解
2017/04/23 Python
Django 生成登陆验证码代码分享
2017/12/12 Python
浅谈python中get pass用法
2019/03/19 Python
python实现几种归一化方法(Normalization Method)
2019/07/31 Python
pytorch 准备、训练和测试自己的图片数据的方法
2020/01/10 Python
Python模拟FTP文件服务器的操作方法
2020/02/18 Python
Keras Convolution1D与Convolution2D区别说明
2020/05/22 Python
匡威比利时官网:Converse Belgium
2017/04/13 全球购物
巴西女装购物网站:Eclectic
2018/04/24 全球购物
Uber Eats台湾:寻找附近提供送餐服务的餐厅
2018/05/07 全球购物
全球最大的房车租赁市场:Outdoorsy
2018/09/19 全球购物
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
护理专业毕业生自我鉴定
2013/10/08 职场文书
内科护士实习自我鉴定
2013/10/17 职场文书
复核员上岗演讲稿
2014/01/05 职场文书
安全协议书
2014/04/23 职场文书
大学生个人学习总结
2015/02/15 职场文书
质量整改通知单
2015/04/21 职场文书
2016年清明节期间群众祭祀活动工作总结
2016/04/01 职场文书
基于Golang 高并发问题的解决方案
2021/05/08 Golang