js中eval详解


Posted in Javascript onMarch 30, 2012

eval函数接收一个参数s,如果s不是字符串,则直接返回s。否则执行s语句。如果s语句执行结果是一个值,则返回此值,否则返回undefined。
需要特别注意的是对象声明语法“{}”并不能返回一个值,需要用括号括起来才会返回值,简单示例如下:

var code1='"a" + 2'; //表达式 
varcode2='{a:2}'; //语句 
alert(eval(code1)); //->'a2' 
alert(eval(code2)); //->undefined 
alert(eval('(' + code2 + ')')); //->[object Object]

可 以看到,对于对象声明语句来说,仅仅是执行,并不能返回值。为了返回常用的“{}”这样的对象声明语句,必须用括号括住,以将其转换为表达式,才能返回其 值。这也是使用JSON来进行Ajax开发的基本原理之一。在例子中可以清楚的看到,第二个alert语句输出的是undefined,而第三个加了括号 后输出的是语句表示的对象。
现在来说本文的重点,如何在函数内执行全局代码。为了说明这个问题,先看一个例子:
var s='global'; //定义一个全局变量 
function demo1(){ 
eval('var s="local"'); 
} 
demo1(); 
alert(s); //->global

很好理解,上面的demo1函数等价于:function demo1(){var s='local';},其中定义了一个局部变量s。
所以最后的输出是global并不是什么奇怪的事情,毕竟大家都能很清楚的区分局部变量和全局变量。
仔细体会一下,可以发现eval函数的特点,它总是在调用它的上下文变量空间(也称为:包,closure)内执行,无论是变量定义还是函数定义都是如此,所以如下的代码会产生函数未定义的错误:
var s='function test(){return 1;}'; //一个函数定义语句 
function demo2(){ 
eval(s); 
} 
demo2(); 
alert(test()); //->error:test is not defined

这是因为test函数在局部空间定义,demo2函数内可以访问到,外面就访问不到了。
而在实际的Ajax开发中,有时我们需要从服务器动态获取代码来执行,以减轻一次载入代码过多的问题,或者是一些代码是通过Javascript自身生成的,希望用eval函数来使其执行。
但这样的动态获取代码的工作一般在函数内完成,比如:
function loadCode(){ 
varcode=getCode(); 
eval(code); 
}

可见eval不可能在全局空间内执行,这就给开发带来了不少问题,也看到过很多人为此郁闷。
不过现在偶终于找到了解决办法,嘿嘿,可以同时兼容IE和Firefox,方法如下:
var X2={} //my namespace:) 
X2.Eval=function(code){ 
if(!!(window.attachEvent && !window.opera)){ 
//ie 
execScript(code); 
}else{ 
//not ie 
window.eval(code); 
} 
}

现在如果要想在函数内定义全局代码,就可以通过调用X2.eval_r(code)方法,一个例子如下:
var s='global'; 
function demo3(){ 
X2.Eval('var s="local"'); 
} 
demo3(); 
alert(s); //->'local'

可见,在demo3函数内重新定义了全局变量s=”local”。
需要注意的是X2.Eval并不返回值,如果要进行表达式的求值,还是用系统的eval函数。X2.Eval设计为仅做全局代码定义用。
其实看到这里,或许有人感觉问题也太容易解决了点,呵呵,但发现这个办法倒是需要些运气和技巧的:
(1)对于IE浏览器,默认已经提供了这样的函数:execScript,用于在全局空间执行代码,只是知道的人还不多。
(2)对于Firefox浏览器,直接调用eval函数,则在调用者的空间执行;如果调用 window.eval则在全局空间执行。这个知道的人估计就更少了。毕竟alert(eval==window.eval)返回true!
Firefox的eval函数的特点的确是很令人奇怪的,但从javascript规范中倒也能找到其来源:
If value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its
name as an Identifier which is the MemberExpression in a CallExpression), or if the eval property is assigned to,
an EvalError exception may be thrown.
意思大概就是说eval函数的执行是和调用者相关的,但并没有说其执行上下文的问题。所以IE和Firefox孰是孰非也就很难说了,大家知道解决办法就好。
Javascript 相关文章推荐
点击文章内容处弹出页面代码
Oct 01 Javascript
JS复制内容到剪切板的实例代码(兼容IE与火狐)
Nov 19 Javascript
封装了一个支持匿名函数的Javascript事件监听器
Jun 05 Javascript
基于JavaScript代码实现自动生成表格
Jun 15 Javascript
JavaScript中最容易混淆的作用域、提升、闭包知识详解(推荐)
Sep 05 Javascript
Bootstrap CSS组件之导航(nav)
Dec 17 Javascript
用React实现一个完整的TodoList的示例代码
Oct 30 Javascript
Vuex入门到上手教程
Jun 20 Javascript
JS div匀速移动动画与变速移动动画代码实例
Mar 26 Javascript
微信小程序数据统计和错误统计的实现方法
Jun 26 Javascript
JS实现打砖块游戏
Feb 14 Javascript
基于js实现数组相邻元素上移下移
May 19 Javascript
关于jquery性能最佳实践的讨论,与求教
Mar 30 #Javascript
从面试题学习Javascript 面向对象(创建对象)
Mar 30 #Javascript
jQuery 自定义函数写法分享
Mar 30 #Javascript
一个JQuery操作Table的代码分享
Mar 30 #Javascript
javascript工具库代码
Mar 29 #Javascript
Web开发之JavaScript
Mar 29 #Javascript
CodeMirror2 IE7/IE8 下面未知运行时错误的解决方法
Mar 29 #Javascript
You might like
php中unserialize返回false的解决方法
2014/09/22 PHP
php面向对象值单例模式
2016/05/03 PHP
php中preg_replace_callback函数简单用法示例
2016/07/21 PHP
yii2利用自带UploadedFile实现上传图片的示例
2017/02/16 PHP
JavaScript入门学习书籍推荐
2008/06/12 Javascript
innerText和innerHTML 一些问题分析
2009/05/18 Javascript
Extjs列表详细信息窗口新建后自动加载解决方法
2010/04/02 Javascript
jquery trim() 功能源代码
2011/02/14 Javascript
用jQuery模拟select下拉框的简单示例代码
2014/01/26 Javascript
javascript实现dom元素可拖动
2016/03/21 Javascript
微信小程序日历组件calendar详解及实例
2017/06/08 Javascript
jquery中有哪些api jQuery主要API
2017/11/20 jQuery
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
关于js对textarea换行符的处理方法浅析
2018/08/03 Javascript
在vue.js中使用JSZip实现在前端解压文件的方法
2018/09/05 Javascript
swiper在angularjs中使用循环轮播失效的解决方法
2018/09/27 Javascript
原生JS实现列表内容自动向上滚动效果
2019/05/22 Javascript
原生js实现抽奖小游戏
2019/06/27 Javascript
jQuery实现轮播图效果demo
2020/01/11 jQuery
vue 二维码长按保存和复制内容操作
2020/09/22 Javascript
Nuxt 项目性能优化调研分析
2020/11/07 Javascript
urllib和BeautifulSoup爬取维基百科的词条简单实例
2018/01/17 Python
python实现祝福弹窗效果
2019/04/07 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
pandas通过字典生成dataframe的方法步骤
2019/07/23 Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
2019/12/11 Python
Python post请求实现代码实例
2020/02/28 Python
Python绘制全球疫情变化地图的实例代码
2020/04/20 Python
Python爬取梨视频的示例
2021/01/29 Python
css3 clip实现圆环进度条的示例代码
2018/02/07 HTML / CSS
整理HTML5中表单的常用属性及新属性
2016/02/19 HTML / CSS
Mamaearth官方网站:印度母婴护理产品公司
2019/10/06 全球购物
英国豪华家具和经典家居饰品购物网站:OKA
2020/06/05 全球购物
个人求职信范文分享
2013/12/13 职场文书
酒店保安领班职务说明书
2014/03/04 职场文书
《登鹳雀楼》教学反思
2014/04/09 职场文书