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 相关文章推荐
jsp js鼠标移动到指定区域显示选项卡离开时隐藏示例
Jun 14 Javascript
JQuery处理json与ajax返回JSON实例代码
Jan 03 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
Oct 17 Javascript
jquery基本选择器匹配多个元素的实现方法
Sep 05 Javascript
基于JS+Canves实现点击按钮水波纹效果
Sep 15 Javascript
JS中input表单隐藏域及其使用方法
Feb 13 Javascript
vuejs绑定class和style样式
Apr 11 Javascript
微信小程序实现多选删除列表数据功能示例
Jan 15 Javascript
js实现ATM机存取款功能
Oct 27 Javascript
使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部
Sep 16 Javascript
vue.js实现照片放大功能
Jun 23 Javascript
vue 将多个过滤器封装到一个文件中的代码详解
Sep 05 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
打造计数器DIY三步曲(中)
2006/10/09 PHP
PHP数据缓存技术
2007/02/14 PHP
php写入mysql中文乱码的实例解决方法
2019/09/17 PHP
javascript对select标签的控制(option选项/select)
2013/01/31 Javascript
讨论html与javascript在浏览器中的加载顺序问题
2013/11/27 Javascript
不想让浏览器运行javascript脚本的方法
2015/11/20 Javascript
给before和after伪元素设置js效果的方法
2015/12/04 Javascript
JavaScript比较两个数组的内容是否相同(推荐)
2017/05/02 Javascript
基于jQuery.i18n实现web前端的国际化
2018/05/04 jQuery
JS使用tween.js动画库实现轮播图并且有切换功能
2018/07/17 Javascript
详解vue项目接入微信JSSDK的坑
2018/12/14 Javascript
Vue代码整洁之去重方法整理
2019/08/06 Javascript
JS前后端实现身份证号验证代码解析
2020/07/23 Javascript
[16:27]DOTA2 HEROS教学视频教你分分钟做大人-艾欧
2014/06/11 DOTA
[54:27]TNC vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python实现的多线程端口扫描工具分享
2015/01/21 Python
python通过floor函数舍弃小数位的方法
2015/03/17 Python
Python内置函数delattr的具体用法
2017/11/23 Python
详解PyTorch手写数字识别(MNIST数据集)
2019/08/16 Python
使用python os模块复制文件到指定文件夹的方法
2019/08/22 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
2020/03/28 Python
使用python实现名片管理系统
2020/06/18 Python
CSS3之边框多颜色Border-color属性使用示例
2013/10/11 HTML / CSS
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
Sephora丝芙兰泰国官方网站:国际知名化妆品购物
2017/11/15 全球购物
意大利值得信赖的在线超级药房:PillolaStore
2020/02/05 全球购物
美国新娘礼品店:The Paisley Box
2020/09/08 全球购物
大专计算机个人求职的自我评价
2013/10/21 职场文书
道德模范先进事迹
2014/02/14 职场文书
党的群众路线教育实践活动心得体会900字
2014/03/07 职场文书
法学自荐信
2014/06/20 职场文书
解约证明模板
2015/06/19 职场文书
公司员工培训管理制度
2015/08/04 职场文书
mysql中关键词exists的用法实例详解
2022/06/10 MySQL
html网页引入svg图片的4种方式
2022/08/05 HTML / CSS