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 相关文章推荐
onpropertypchange
Jul 01 Javascript
用Node.js通过sitemap.xml批量抓取美女图片
May 28 Javascript
JavaScript判断undefined类型的正确方法
Jun 30 Javascript
javascript仿百度输入框提示自动下拉补全
Jan 07 Javascript
jQuery easyui的validatebox校验规则扩展及easyui校验框validatebox用法
Jan 18 Javascript
jQuery获取radio选中项的值实例
Jun 18 Javascript
使用 bootstrap modal遇到的问题小结
Nov 09 Javascript
原生JS和jQuery操作DOM对比总结
Jan 19 Javascript
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 Javascript
微信小程序之页面跳转和参数传递的实现
Sep 29 Javascript
css和js实现弹出登录居中界面完整代码
Nov 26 Javascript
jQuery+ajax读取json数据并按照价格排序示例
Mar 28 jQuery
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全排列递归算法代码
2012/10/09 PHP
基于php设计模式中工厂模式详细介绍
2013/05/15 PHP
8个必备的PHP功能实例代码
2013/10/27 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
简介PHP的Yii框架中缓存的一些高级用法
2016/03/29 PHP
CI框架表单验证实例详解
2016/11/21 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
基于ThinkPHP实现的日历功能实例详解
2017/04/15 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
ajax 缓存 问题 requestheader
2010/08/01 Javascript
浅析js中2个等号与3个等号的区别
2013/08/06 Javascript
Javascript中的String对象详谈
2014/03/03 Javascript
JavaScript动态创建form表单并提交的实现方法
2015/12/10 Javascript
JS随机洗牌算法之数组随机排序
2016/03/23 Javascript
javascript实现延时显示提示框特效代码
2016/04/27 Javascript
JS弹出层遮罩,隐藏背景页面滚动条细节优化分析
2016/04/29 Javascript
jQuery可见性过滤选择器用法示例
2016/09/09 Javascript
如何使用headjs来管理和异步加载js
2016/11/29 Javascript
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
2018/02/11 Javascript
[41:52]2018DOTA2亚洲邀请赛3月29日小组赛B组Effect VS Secret
2018/03/30 DOTA
python计算时间差的方法
2015/05/20 Python
python常用知识梳理(必看篇)
2017/03/23 Python
Python中实例化class的执行顺序示例详解
2018/10/14 Python
python requests抓取one推送文字和图片代码实例
2019/11/04 Python
TensorFlow Saver:保存和读取模型参数.ckpt实例
2020/02/10 Python
Python numpy多维数组实现原理详解
2020/03/10 Python
Python Selenium安装及环境配置的实现
2020/03/17 Python
乐高官方旗舰店:LEGO积木玩具
2019/04/06 全球购物
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
金融管理应届生求职信
2014/02/20 职场文书
党委领导班子整改方案
2014/09/30 职场文书
观后感格式
2015/06/19 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
2016年六一文艺汇演开幕词
2016/03/04 职场文书
Python字典的基础操作
2021/11/01 Python