当前位置: 首页 > 图文教程 > 网络编程 > Javascript > Javascript学习笔记4 Eval函数

Javascript
Jquery 基础学习笔记
javascript 进度条的几种方法
Jquery中的offset()和position()深入剖析
基于Jquery 好友选择器V2.0
AJAX 仿EXCEL表格功能
网页和浏览器兼容性问题汇总(draft1)
JAVASCRIPT 点击显示 隐藏层
jQuery 学习 几种常用方法
JavaScript 动态改变图片大小
javascript 树控件 比较好用
Javascript Tab 导航插件 (23个)
JavaScript talbe表中指定位置插入一行的实现代码 修正版
js 操作css实现代码
Javascript 错误处理的几种方法
FireFox JavaScript全局Event对象
jquery.alert 弹出式复选框实现代码
jQuery Ajax文件上传(php)
jquery 上下滚动广告
JS 拼图游戏 面向对象,注释完整。
javascript 控制图片播放代码

Javascript学习笔记4 Eval函数


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-20   浏览: 405 ::
收藏到网摘: n/a

在初学JS的时候就知道这个函数,却一直没有了解过他的用途,也一直都是睁一只眼闭一只眼,这次来深入地了解一下这个函数的作用。 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在一般的情况中是很少被用到的,我们是完全可以避免来使用它的。 "