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函数的更多相关文章

  1. JavaScript中的eval()函数

    和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作. eval(“1+2” ...

  2. java ScriptEngine 使用 (支持JavaScript脚本,eval()函数等)

    Java SE 6最引人注目的新功能之一就是内嵌了脚本支持.在默认情况下,Java SE 6只支持JavaScript,但这并不以为着Java SE 6只能支持JavaScript.在Java SE ...

  3. JavaScript中的eval()函数详解

    和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作     eval(“1 ...

  4. javascript中的eval函数

    eval()只有一个参数,如果传入的参数不是字符串,则直接返回这个参数.否则会将字符串当成js代码进行编译,如果编译失败则抛出语法错误(SyntaxError)异常.如果编译成功则开始执行这段代码,并 ...

  5. javascript中的eval()函数应用以及要点

    eval是干嘛用的?eval是直接将一段字符串作为参数,交给JS引擎预编译器进行动态分析并执行代码.如下: //调试台输出,你可以理解为console.log,再不理解就理解成alert也没事 var ...

  6. JavaScript中Eval()函数的作用

    这一周感觉没什么写的,不过在研究dwz源码的时候有一个eval()的方法不是很了解,分享出来一起学习 -->首先来个最简单的理解 eval可以将字符串生成语句执行,和SQL的exec()类似. ...

  7. Javascript eval()函数 基础回顾

    如果您想详细了解ev al和JSON请参考以下链接: eval  :https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Glo ...

  8. JavaScript中eval()函数

    eval调用时,实例为eval( "( javascript代码 )" ), eval() 函数可将字符串转换为代码执行,并返回一个或多个值.

  9. eval函数的工作原理

    如果您想详细了解eval和JSON请参考以下链接: eval  :https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Glob ...

随机推荐

  1. Gora官方范例

    参考官方文档:http://gora.apache.org/current/tutorial.html 项目代码见:https://code.csdn.net/jediael_lu/mygoradem ...

  2. clearInterval()与setInterval()的应用

    1.setInterval()按照一定的周期调用函数2.clearInterval()取消setInterval()的周期调用 例如:图片轮播中的clearInterval()与setInterval ...

  3. 自定义View—颜色

    一.颜色通道的意思 ARGB888.ARGB444.RGB565.Alpha8的区别 二.如何自定义颜色 ①.首先ARGB分别表示

  4. Java 中字符串的子串搜索

    基友前两天参加了阿里的实习生面试,问了个问题,就是关于字符串的子串搜索的问题.想想实现方式无非就是两层循环,但是 java 中是有现成实现的,于是我就去查查源码,看看 java 语言怎么实现这个的,发 ...

  5. 利用程序将.jrxml导出为.jasper文件并用PDF显示(2)

    直接在Web项目中使用.jasper文件,其实在软件项目开发时,.jrxml文件经常修改,而且.jrxml还要在项目中进行保留备份,所以较为流行的做法是在项目中使用.jrxml来生成.jasper文件 ...

  6. DataTables选择行并删除(删除单行)

    $(document).ready(function() { var table = $('#example').DataTable(); $('#example tbody').on( 'click ...

  7. Bootstrap 实例 - 模态框(Modal)插件

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. AFNetworking 使用 核心代码

    ///////////////////////////以前用法///////////////////////////////////////////////////////////// //使用AFH ...

  9. iPhone 和Android应用,特殊的链接:打电话,短信,email;

    http://ice-k.iteye.com/blog/1426526 下面的这篇文章主要是说,网页中的链接如何写,可以激活电话的功能. 例如,页面中展示的是一个电话号码,当用户在手机浏览器里面点击这 ...

  10. Codeforces 358D Dima and Hares

    http://codeforces.com/contest/358/problem/D 题意:给出n个数,每个数取走的贡献与相邻的数有关,如果取这个数的时候,左右的数都还没被取,那么权值为a,如果左右 ...