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 相关文章推荐
在浏览器中获取当前执行的脚本文件名的代码
Jul 19 Javascript
Jquery阻止事件冒泡 event.stopPropagation
Dec 11 Javascript
js事件监听机制(事件捕获)总结
Aug 08 Javascript
微信公众平台开发教程(五)详解自定义菜单
Dec 02 Javascript
用v-html解决Vue.js渲染中html标签不被解析的问题
Dec 14 Javascript
Angular的模块化(代码分享)
Dec 26 Javascript
微信小程序图片选择区域裁剪实现方法
Dec 02 Javascript
微信小程序实现聊天对话(文本、图片)功能
Jul 06 Javascript
vue基于element-ui的三级CheckBox复选框功能的实现代码
Oct 15 Javascript
Vue中JS动画与Velocity.js的结合使用
Feb 13 Javascript
vue按需加载实例详解
Sep 06 Javascript
详解Node.js如何处理ES6模块
May 15 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
PHP对字符串的递增运算分析
2010/08/08 PHP
PHP将页面中点击数量高的链接进行高亮显示的方法
2016/05/30 PHP
Thinkphp通过一个入口文件如何区分移动端和PC端
2017/04/18 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
2019/12/01 PHP
JavaScript创建命名空间(namespace)的最简实现
2007/12/11 Javascript
JS面向对象、prototype、call()、apply()
2009/05/14 Javascript
IE和Firefox下event事件杂谈
2009/12/18 Javascript
jQuery UI Autocomplete 体验分享
2012/02/14 Javascript
JQuery获取表格数据示例代码
2014/05/26 Javascript
Node.js中安全调用系统命令的方法(避免注入安全漏洞)
2014/12/05 Javascript
JavaScript设计模式之单件模式介绍
2014/12/28 Javascript
javascript实现图片自动和可控的轮播切换特效
2015/04/13 Javascript
jQuery实现的个性化返回底部与返回顶部特效代码
2015/10/30 Javascript
浅谈js里面的InttoStr和StrtoInt
2016/06/14 Javascript
全面了解addEventListener和on的区别
2016/07/14 Javascript
详解基于javascript实现的苹果系统底部菜单
2016/12/02 Javascript
vue.js的手脚架vue-cli项目搭建的步骤
2017/08/30 Javascript
纯JavaScript实现实时反馈系统时间
2017/10/26 Javascript
Vue实现手机扫描二维码预览页面效果
2020/05/28 Javascript
如何通过JS实现日历简单算法
2020/10/14 Javascript
ubuntu系统下 python链接mysql数据库的方法
2017/01/09 Python
python TKinter获取文本框内容的方法
2018/10/11 Python
解决python-docx打包之后找不到default.docx的问题
2020/02/13 Python
利用4行Python代码监测每一行程序的运行时间和空间消耗
2020/04/22 Python
对python中arange()和linspace()的区别说明
2020/05/03 Python
HTML5不支持frameset的两种解决方法
2016/11/14 HTML / CSS
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
2019年.net常见面试问题
2012/02/12 面试题
自荐信结尾
2013/10/27 职场文书
生产管理的三大手法
2013/11/11 职场文书
区长工作作风个人整改措施
2014/10/01 职场文书
2019年鼓励无偿献血倡议书
2019/09/17 职场文书
SqlServer: 如何更改表的文件组?(进而改变存储位置)
2021/04/05 SQL Server
python opencv人脸识别考勤系统的完整源码
2021/04/26 Python
深入理解java.lang.String类的不可变性
2021/06/27 Java/Android
GoFrame基于性能测试得知grpool使用场景
2022/06/21 Golang