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 相关文章推荐
javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象
Jan 15 Javascript
javaScript(JS)替换节点实现思路介绍
Apr 17 Javascript
Javascript中匿名函数的多种调用方式总结
Dec 06 Javascript
Bootstrap三种表单布局的使用方法
Jun 21 Javascript
AngularJS Ajax详解及示例代码
Aug 17 Javascript
手机端图片缩放旋转全屏查看PhotoSwipe.js插件实现
Aug 25 Javascript
bootstrap读书笔记之CSS组件(上)
Oct 17 Javascript
Angular使用 ng-img-max 调整浏览器中的图片的示例代码
Aug 17 Javascript
解决layui 表单元素radio不显示渲染的问题
Sep 04 Javascript
JS document form表单元素操作完整示例
Jan 13 Javascript
javascript实现计算器功能
Mar 30 Javascript
js实现上传按钮并显示缩略图小轮子
May 04 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的配置文件php.ini
2006/10/09 PHP
对squid中refresh_pattern的一些理解和建议
2009/04/17 PHP
ecshop 批量上传(加入自定义属性)
2012/03/20 PHP
php数据类型判断函数有哪些
2013/09/23 PHP
PHP针对JSON操作实例分析
2015/01/12 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
laravel清除视图缓存的代码
2019/10/23 PHP
PHP如何使用cURL实现Get和Post请求
2020/07/11 PHP
javascript while语句和do while语句的区别分析
2007/12/08 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
vue.js图片转Base64上传图片并预览的实现方法
2018/08/02 Javascript
如何将HTML字符转换为DOM节点并动态添加到文档中详解
2018/08/19 Javascript
webpack4 SCSS提取和懒加载的示例
2018/09/03 Javascript
vue+axios+element ui 实现全局loading加载示例
2018/09/11 Javascript
记一次vue去除#问题处理经过小结
2019/01/24 Javascript
JavaScript的级联函数用法简单示例【链式调用】
2019/03/26 Javascript
vue实现滑动切换效果(仅在手机模式下可用)
2020/06/29 Javascript
Vue 中 filter 与 computed 的区别与用法解析
2019/11/21 Javascript
js、jquery实现列表模糊搜索功能过程解析
2020/03/27 jQuery
vue keep-alive的简单总结
2021/01/25 Vue.js
在Mac OS上部署Nginx和FastCGI以及Flask框架的教程
2015/05/02 Python
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
Python与R语言的简要对比
2017/11/14 Python
python 自动批量打开网页的示例
2019/02/21 Python
python实现最大子序和(分治+动态规划)
2019/07/05 Python
解决Python二维数组赋值问题
2019/11/28 Python
Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法
2019/12/17 Python
python 错误处理 assert详解
2020/04/20 Python
使用HTML5在网页中嵌入音频和视频播放的基本方法
2016/02/22 HTML / CSS
写自荐信的注意事项
2014/03/09 职场文书
法律七进实施方案
2014/03/15 职场文书
领导批评与自我批评范文
2014/10/16 职场文书
2016年教师节感恩寄语
2015/12/04 职场文书
2016年党员干部公开承诺书
2016/03/24 职场文书
Pygame游戏开发之太空射击实战敌人精灵篇
2022/08/05 Python