• 介绍
    • 计算由源代码组成的字符串, 用eval("")来运行
    • eval()是一个函数,但设计上更像运算符。
      • 限制eval()函数使它更像运算符
  • eval()
    • 一个参数,如果不传入字符串,则直接返回传入的参数。
      • 传入字符串, 则编译该字符串
        • 失败则抛出语法错误异常(SyntaxError),成功则开始执行这段代码
        • 执行成功,返回字符串中最后一个语句的值。最后语句没有值,返回undefined
        • 执行中抛出异常, 该异常将调用传递给eval()[?]
    • eval的作用域是当前作用域, 如eval(“var y = 3;”)
    • 用eval向函数中粘贴代码片段是无意义的,如
      • var foo = function(a){eval(a)};
      • foo(“return;”); # 执行eval(a)的上下文是全局的, 会抛出return not in function错误
    • eval作为单独脚本,如eval(” y = 1;“)是有意义的
  • 问题
    • eval()中的代码,解释器不能分析和优化
      • eval()可以改变局部变量,对优化是很大的问题
    • eval()的函数名可以被赋予其他名字(与运算符的区别)
      • var f = eval;
      • var g = f;
      • 这样解释器无法优化任何调用g()的函数
        • 所以ECMAScript规定不可以对eval()赋予别名,会抛出EvalError异常
        • 实际上,大多数实现并不这么做。别名调用时, 会当作顶层全局代码来执行
        • 这样不会修改局部变量的值,不影响优化
    • ECMAScript 5规定
      • 直接eval(direct eval), 总是在调用它的上下文作用域执行
      • 间接调用(指别名调用)则作为顶层代码执行,不能读、写、定义局部变量 # 间接eval是有用的特性,允许在局部作用域执行上下文无依赖的脚本
    • ie9之前的不同
      • 别名调用eval()是局部调用
      • 用execScript()来全局eval调用 # 与eval不同在于总是返回null
    • ECMAScript 5 严格模式
      • eval作为保留字, 不能用别名覆盖(更像运算符)
      • eval中的字符串以”use strict”指令开始
      • 可以使用和更改局部变量,不可以定义新的变量