- 介绍
- 计算由源代码组成的字符串, 用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()的函数名可以被赋予其他名字(与运算符的区别)
- 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”指令开始
- 可以使用和更改局部变量,不可以定义新的变量