JavaScript中的eval()函数使用介绍


Posted in Javascript onDecember 31, 2014

在JavaScript中,可以使用eval()函数来解析字符串中的JavaScript代码,并返回相应的代码执行结果:

console.log(eval("42 * 2"));//84

就本质而言,eval()是JavaScript全局对象的一个函数。比如,上述代码等价于:

console.log(this.eval("42 * 2"));//84

不过在使用eval()语句时,一般都采用上述第一种做法,也即忽略全局对象直接使用eval()。

eval()的使用

基于以下两个原因,除非确实需要,不然应尽量避免在代码中使用eval()语句:

1.从逻辑上来说,字符串应该用于储存程序运行过程中的内容、信息,而不应该用于储存具体的计算逻辑。
2.由于eval()参数为字符串,而对于一段字符串无法词法进行,因此对于eval()调用语句,JavaScript解释器无法进行优化。

eval()的返回值

eval()的返回值遵循以下规则:

1.如果eval()的参数不是字符串,那么eval()将直接返回参数。
2.如果eval()的参数是字符串,那么eval()将这个字符串解析成代码后进行执行,并返回最后一行代码执行的结果。
3.如果字符串无法解析成合法的代码,eval()将抛出SyntaxError错误。
4.如果字符串能够被解析成合法的代码,但是在执行这一代码过程中报错,那么这个错误会上报给eval()语句,并由eval()抛出。

console.log(eval([1,2,3]));//[1, 2, 3]

console.log(typeof eval([1,2,3]));//object
console.log(eval("42 */ 2"));//SyntaxError

console.log(eval("42 * 2; 22 * 3;"));//66. eval returns the result of last expression/statement

console.log(eval("null.toString()"));//TypeError, exception in eval-ed code will be propagated outside eval().

变量环境(variable environment)

JavaScript中eval()有一个重要的特性:eval()参数字符串中的代码可以访问外部代码中的变量,同时也可以将参数字符串代码中新建的变量暴露给外部代码。也即,如果eval()参数字符串可以被合法解析,那么JS会将解析后的代码替换掉eval()所在的那一行:

//variable environment

var a = 108;

console.log(eval("function double(x){return x*2;} a = double(a)"));

console.log(a);//216

console.log(double(33));//66

值得注意的是,实现上述特性的前提是eval()参数字符串中的代码可以被合法解析。除了代码语法正确外,JS还要求eval()参数字符串中的代码必须“自成一体”:仅就参数字符串中的代码而言,代码必须是有意义的。比如,无法将诸如“return;”这样的字符串传给eval()函数:

function test(){

  var s = "test";

  eval("return s;");

}

test();//SyntaxError: return not in function

如果直接使用eval()函数,那么eval()参数字符串中的代码所访问的变量是eval()语句所在function的那些变量,也即eval()函数所使用的变量环境是“本地变量环境”。如果不直接使用eval()函数,而是使用一个同样指向eval()函数的新变量,那么相应参数字符串中的代码所访问的变量均为全局变量,也即eval()函数所使用的变量环境是“全局变量环境”:

//local variable environment and global variable environment

var renamed = eval;

var x = "origin", y = "origin";

function f(){

  var x = "new";

  eval("x += 'Changed';");

  return x;

}

function g(){

  var y = "new";

  renamed("y += 'Changed';");

  return y;

}

console.log(f(), x);//newChanged origin

console.log(g(), y);//new originChanged

不过,值得注意的是,IE6、7、8中的行为与此不同。在IE6、7、8中,即使eval()函数被重命名,所使用的也依然是“本地变量环境”。

Javascript 相关文章推荐
javascript生成json数据简单示例分享
Feb 14 Javascript
Javascript 函数parseInt()转换时出现bug问题
May 20 Javascript
JavaScript中的类(Class)详细介绍
Dec 30 Javascript
原生javascript实现图片无缝滚动效果
Feb 12 Javascript
JavaScript实现翻页功能(附效果图)
Feb 16 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
Feb 21 Javascript
js实现拖拽功能
Mar 01 Javascript
简单的Vue SSR的示例代码
Jan 12 Javascript
CKeditor4 字体颜色功能配置方法教程
Jun 26 Javascript
javascript实现拖拽碰撞检测
Mar 12 Javascript
用JS实现选项卡
Mar 23 Javascript
vue element ui validate 主动触发错误提示操作
Sep 21 Javascript
JSONP跨域GET请求解决Ajax跨域访问问题
Dec 31 #Javascript
JavaScript中的异常捕捉介绍
Dec 31 #Javascript
JavaScript中对象介绍
Dec 31 #Javascript
JavaScript中用字面量创建对象介绍
Dec 31 #Javascript
javascript设计模式之中介者模式Mediator
Dec 30 #Javascript
javascript实现window.print()去除页眉页脚
Dec 30 #Javascript
Javascript访问器属性实例分析
Dec 30 #Javascript
You might like
mysql_num_rows VS COUNT 效率问题分析
2011/04/23 PHP
基于php-fpm 参数的深入理解
2013/06/03 PHP
php常用hash加密函数
2014/11/22 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
Javascript实现的鼠标经过时播放声音
2010/05/18 Javascript
jquery加载页面的方法(页面加载完成就执行)
2011/06/21 Javascript
js改变img标签的src属性在IE下没反应的解决方法
2013/07/23 Javascript
jquery实现图片渐变切换兼容ie6/Chrome/Firefox
2013/08/02 Javascript
为开发者准备的10款最好的jQuery日历插件
2014/02/04 Javascript
做好七件事帮你提升jQuery的性能
2014/02/06 Javascript
jQuery中ready事件用法实例
2015/01/19 Javascript
jQuery插件slides实现无缝轮播图特效
2015/04/17 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
Bootstrap4一次重大更新 几乎涉及每行代码
2016/05/16 Javascript
浅谈js内置对象Math的属性和方法(推荐)
2016/09/19 Javascript
node学习记录之搭建web服务器教程
2017/02/16 Javascript
vue中eventbus被多次触发以及踩过的坑
2017/12/02 Javascript
详解Angular系列之变化检测(Change Detection)
2018/02/26 Javascript
详解Vue用cmd创建项目
2019/02/12 Javascript
微信小程序结合Storage实现搜索历史效果
2019/05/18 Javascript
layui当点击文本框时弹出选择框,显示选择内容的例子
2019/09/02 Javascript
js+canvas绘制图形验证码
2020/09/21 Javascript
[06:13]DOTA2进化论(修改版)
2013/10/08 DOTA
Python面向对象之继承代码详解
2018/01/29 Python
mac下如何将python2.7改为python3
2018/07/13 Python
python文件操作之批量修改文件后缀名的方法
2018/08/10 Python
详细介绍pandas的DataFrame的append方法使用
2019/07/31 Python
详解从Django Allauth中进行登录改造小结
2019/12/18 Python
Python tkinter三种布局实例详解
2020/01/06 Python
Toppik顶丰增发纤维官网:解决头发稀疏
2017/12/30 全球购物
美国最大的户外装备和服装购物网站:Backcountry
2019/10/15 全球购物
澳大利亚领先的时尚内衣零售商:Bras N Things
2020/07/28 全球购物
linux面试题参考答案(6)
2016/06/23 面试题
无房证明范本
2014/09/17 职场文书
教师工作表现自我评价
2015/03/05 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书