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 ...
随机推荐
- hdu5347 MZL's chemistry(打表)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud MZL's chemistry Time Limit: 2000/1000 MS ...
- C++常量指针与常量数据
常量指针即指针是常量的,一但声明指向某个数据后不能被更改,但是指向的数据可以被更改.声明格式如下: ; int * const p = &demo; 常量数据是指数据是常量的,一但被初始化后不 ...
- js迭代器模式
在迭代器模式中,通常有一个包含某种数据的集合的对象.该数据可能储存在一个复杂数据结构内部,而要提供一种简单 的方法能够访问数据结构中的每个元素. 实现如下: //迭代器模式 var agg = (fu ...
- React/React Native的 ES5 ES6 写法对照
ES5 ES6 模块 var React = require("react-native); var { Image, Text, View } = React; import Re ...
- 利用java反射机制对方法进行调用
http://blog.csdn.net/coolcoffee168/article/details/5835143
- jquery中checkbox全选失效的解决方法
这篇文章主要介绍了jquery中checkbox全选失效的解决方法,需要的朋友可以参考下 如果你使用jQuery 1.6 ,代码if ( $(elem).attr(“checked”) ),将 ...
- 行为级和RTL级的区别(转)
转自:http://hi.baidu.com/renmeman/item/5bd83496e3fc816bf14215db RTL级,registertransferlevel,指的是用寄存器这一级别 ...
- 微软推荐的Get a code signing certificate流程和链接
Get a code signing certificate Before you can establish a Windows Dev Center hardware dashboard ac ...
- 《Programming WPF》翻译 第5章 3.命名属性
原文:<Programming WPF>翻译 第5章 3.命名属性 通过把同样的内嵌样式提升到资源中(正如第一章介绍的),我们可以给它一个名字,以及按名字使用它在我们的Button实例上, ...
- 【转】【Android】HAL分析
原文网址:http://www.cnblogs.com/lcw/p/3335505.html HAL概述 以下是基于android4.0.3,对应其他低版本的代码,可能有所差异,但基本大同小异. An ...