JavaScript当中的eval函数
eval函数
eval函数接收一个由JavaScript语句组成的字符串,并且返回字符串中最后一条语句的返回值,如果最后一条语句没有返回值,那么eval函数返回undefined。如果传递给eval函数的不是字符串,那么传递什么,eval就返回什么。
调用eval函数的三种情况
当调用eval函数时,JavaScript会创建新的执行环境,总共有三种情形:
1 直接调用
直接调用时,eval函数相关的执行环境属性ThisBinding,LexicalEnvironment,VariableEnvironment的值如下:
a) ThisBinding是调用eval函数时,调用方执行环境的ThisBinding
b) LexicalEnvironment是调用eval函数时,调用方执行环境的LexicalEnvironment
c) VariableEnvironemnt是调用eval函数时,调用方执行环境的VariableEnvironment
假设有如下JavaScript代码(f在全局环境下被调用):
function f() {
var i = 1;
eval("var y = 2; i = 3");
alert(y);
}
f();
当eval函数被调用时,执行环境栈如下图所示:

需要注意的是,当新建一个执行环境时要进行标识符绑定,绑定的标识符放到执行环境VariableEnvironment指向的Lexical Environment中。由于eval函数的VariableEnvironment与调用方(即调用eval的函数f)的VariableEnvironment指向同一个Lexical Environment,因此,在eval中声明的局部变量y被绑定到调用方的Lexical Environment中,这导致当eval函数调用结束,与eval相关的执行环境被弹出栈顶,而在eval中声明的局部变量y在函数f中仍然可以访问得到。因此,上面代码中alert会显示2,而不是报错。
2 间接调用
所谓间接调用,即将eval赋值给另一个变量后在调用,如下面代码所示:
var g = eval;
g("var y = 1;");
间接调用也会创建新的执行环境,不同之处在于新执行环境的ThisBinding,LexicalEnvironment,VariableEnvironment的值不同:
a) ThisBinding为全局对象
b) LexicalEnvironment为全局执行环境的的LexicalEnvironment
c) VariableEnvironment为全局执行环境的VariableEnvironment
假如有下面的代码:
function f() {
var i = 1;
var gEval = eval;
gEval("var y = 2; i = 3");
alert(y);
}
f();
当调用gEval时,执行环境栈如下图所示:

可以看到,在gEval当中声明的变量都绑定到了全局执行环境当中,需要注意的是,gEval当中的变量i并不是引用的函数f的变量i,因为从gEval的作用域链访问不到函数f的局部变量i,此时gEval中的变量i就等价于没有使用关键字var声明了一个全局变量。函数f的alert语句仍然显示2,只是此时访问的y是全局环境中的变量y。
3 严格模式下的eval
在严格模式下,eval的LexicalEnvironment,VariableEnvironment指向属于eval自己的Lexcial Environment,而不是调用方的Lexical Environment,但是ThisBinding还是调用方的ThisBinding。同时,在严格模式下如果eval直接调用,那么eval的Lexical Environment的outer指针指向调用方的Lexical Environment,否则,如果是间接调用,那么eval的Lexical Environment的outer指针指向全局环境的Lexical Environment。
假如有如下代码:
"use strict"; //使用严格模式
function f() {
var i = 1;
eval("var y = 2; i = 3");
alert(y);
}
f();
当调用eval时,执行环境栈如下图所示:

从图可以看到,eval中声明的局部变量y被绑定到自己的Lexical Environment中,eval中的i访问的是函数f声明的局部变量i。由于变量y被绑定在eval自己的Lexical Environment中,因此当eval运行结束,相关的执行环境被弹出栈顶之后,函数f是访问不到变量y的,因此alert要报错。
IE中的eval
IE9之前,无论eval是直接调用还是间接调用,eval都当成直接调用处理,如果需要有间接调用的效果,可以使用IE提供的execScript函数。
参考资料:
JavaScript权威指南
ECMA-262
JavaScript当中的eval函数的更多相关文章
- JavaScript中的eval()函数
和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作. eval(“1+2” ...
- java ScriptEngine 使用 (支持JavaScript脚本,eval()函数等)
Java SE 6最引人注目的新功能之一就是内嵌了脚本支持.在默认情况下,Java SE 6只支持JavaScript,但这并不以为着Java SE 6只能支持JavaScript.在Java SE ...
- JavaScript中的eval()函数详解
和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作 eval(“1 ...
- javascript中的eval函数
eval()只有一个参数,如果传入的参数不是字符串,则直接返回这个参数.否则会将字符串当成js代码进行编译,如果编译失败则抛出语法错误(SyntaxError)异常.如果编译成功则开始执行这段代码,并 ...
- javascript中的eval()函数应用以及要点
eval是干嘛用的?eval是直接将一段字符串作为参数,交给JS引擎预编译器进行动态分析并执行代码.如下: //调试台输出,你可以理解为console.log,再不理解就理解成alert也没事 var ...
- JavaScript中Eval()函数的作用
这一周感觉没什么写的,不过在研究dwz源码的时候有一个eval()的方法不是很了解,分享出来一起学习 -->首先来个最简单的理解 eval可以将字符串生成语句执行,和SQL的exec()类似. ...
- Javascript eval()函数 基础回顾
如果您想详细了解ev al和JSON请参考以下链接: eval :https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Glo ...
- JavaScript中eval()函数
eval调用时,实例为eval( "( javascript代码 )" ), eval() 函数可将字符串转换为代码执行,并返回一个或多个值.
- eval函数的工作原理
如果您想详细了解eval和JSON请参考以下链接: eval :https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Glob ...
随机推荐
- mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in
从字面的意思上说:这个函数要被弃用,请使用 mysqlli 或者是 PDO 代替 然后就查手册发现没说,大家一定要查官方最新的手册
- hdfs的实现机制和文件系统概念
1.HDFS的诞生背景: 数据量太大,在一个结点(机器)存不下.所以需要分布式存储,HDFS就是hadoop的分布式文件系统,来存储分布式数据. 2.共享文件系统也是一种分布式存储但有缺点:1.并发差 ...
- List myList=new ArrayList()的理解
ArrayList不是继承List接口,是实现了List接口.你写成ArrayList arrayList = new ArrayList();这样不会有任何问题.和List list = new A ...
- cocos2d安卓android长音效播放不完全
是因为安卓限制了音效的内存,一般把mp3的比特率压缩一下.就可以搞定了.
- 统计的基本操作语法 <第五篇>
1.创建统计语法: CREATE STATISTICS statistics_name ON { table_or_indexed_view_name } ( column [ ,...n ] ) [ ...
- Android,监控ContentProvider的数据改变
有时候应用中需要监听ContentProvider的改变并提供响应,这时候就要利用ContentObserver类了 不管是ContentProvider中实现的,insert,delete,upda ...
- 【转】使用adb命令对手机进行截屏(截图)保存到电脑,SDCard
原文网址:http://blog.csdn.net/huangyabin001/article/details/29198367 adb shell /system/bin/screencap -p ...
- HDu 5433 Xiao Ming climbing (BFS)
题意:小明因为受到大魔王的诅咒,被困到了一座荒无人烟的山上并无法脱离.这座山很奇怪: 这座山的底面是矩形的,而且矩形的每一小块都有一个特定的坐标(x,y)和一个高度H. 为了逃离这座山,小明必须找到大 ...
- 使用cx_Freeze 将python3代码打包成.exe程序
在这里分享一下如何在py3下使用cx_Freeze打包pyqt5的程序 首先吐槽下,深深鄙视一下百度,各种百度各种没有,之前我在py2.7下使用pyqt4开发过一个小软件,用的是py2exe进行打包的 ...
- poj 1088 滑雪问题
滑雪问题 import java.util.Scanner; public class Main{ static int a[][],r,c; public static void main(Stri ...