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 EasyUI 中文API Layout(Tabs)
Apr 27 Javascript
zShowBox 图片放大展示jquery版 兼容性
Sep 24 Javascript
js新闻滚动 js如何实现新闻滚动效果
Jan 07 Javascript
JavaScript 和 Java 的区别浅析
Jul 31 Javascript
ExtJS4中使用mixins实现多继承示例
Dec 03 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
阻止表单提交按钮多次提交的完美解决方法
May 16 Javascript
AngularJS 入门教程之HTML DOM实例详解
Jul 28 Javascript
详解Vuejs2.0之异步跨域请求
Apr 20 Javascript
javascript实现循环广告条效果
Dec 12 Javascript
JQuery绑定事件四种实现方法解析
Dec 02 jQuery
LayUI+Shiro实现动态菜单并记住菜单收展的示例
May 06 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排序算法之归并排序(Merging Sort)实例详解
2018/04/21 PHP
javascript for循环设法提高性能
2010/02/24 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
javascript中返回顶部按钮的实现
2015/05/05 Javascript
JS+DIV+CSS实现仿表单下拉列表效果
2015/08/18 Javascript
基于html5和nodejs相结合实现websocket即使通讯
2015/11/19 NodeJs
学习JavaScript设计模式(单例模式)
2015/11/26 Javascript
使用JavaScript获取URL中的参数(两种方法)
2016/11/16 Javascript
浅谈React深度编程之受控组件与非受控组件
2017/12/26 Javascript
JavaScript数组及常见操作方法小结
2019/11/13 Javascript
2019最新21个MySQL高频面试题介绍
2020/02/06 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
[44:15]国士无双DOTA2 6.82版本详解(上)
2014/09/28 DOTA
[05:16]《大圣!大圣》——DOTA2新英雄齐天大圣配音李世宏老师专访
2016/12/13 DOTA
[00:57]深扒TI7聊天轮盘语音出处5
2017/05/11 DOTA
python中的编码知识整理汇总
2016/01/26 Python
python实现定时提取实时日志程序
2018/06/22 Python
Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统
2019/09/05 Python
Win下PyInstaller 安装和使用教程
2019/12/25 Python
Python如何实现后端自定义认证并实现多条件登陆
2020/06/22 Python
使用jupyter notebook运行python和R的步骤
2020/08/13 Python
图片上传插件ImgUploadJS:用HTML5 File API 实现截图粘贴上传、拖拽上传
2016/01/20 HTML / CSS
Hotels.com台湾:饭店订房网
2017/09/06 全球购物
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
微软巴西官方网站:Microsoft Brasil
2019/09/26 全球购物
大专生找工作自荐书
2014/06/10 职场文书
租房安全协议书
2014/08/20 职场文书
反腐倡廉剖析材料
2014/09/30 职场文书
街道党工委党的群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
自我检讨书怎么写
2015/05/07 职场文书
法律意见书范文
2015/06/04 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
《观察物体》教学反思
2016/02/17 职场文书
为什么不建议在go项目中使用init()
2021/04/12 Golang
解决Mysql的left join无效及使用的注意事项说明
2021/07/01 MySQL
Vue监视数据的原理详解
2022/02/24 Vue.js