表达式计算:eval
和 PHP 一样,JavaScript 也可以解释运行由 JavaScript 源代码组成的字符串,并产生一个值,JavaScript 通过全局函数 eval()
来完成这一工作:
eval("1+2")
注:尽量少用或不用
eval()
,因为动态执行的代码无法被解释器分析和优化。
eval
eval()
只有一个参数,如果这个参数不是字符串会被直接返回,如果是字符串的话,会把字符串当做 JavaScript 代码进行编译,如果编译失败抛出语法错误异常,编译成功则开始执行这段代码,并返回字符串中最后一条语句或表达式的值,如果没有值返回 undefined
。
关于 eval()
最重要的是它使用了调用它的变量作用域环境,也就是说,它查找变量的值和定义新变量和函数的操作和局部作用域中的代码完全一致,如果一个函数体内定义了一个局部变量 x
,调用 eval("x")
会返回这个局部变量的值,如果调用了 eval("x=1")
会将函数体内的 x
值设为1
,甚至可以通过 eval()
来声明一个局部函数:
eval("function f() {return x+1;}")
如果在最顶层代码中调用 eval()
,则作用于全局变量和全局函数:
全局 eval
eval()
具有改变局部变量的能力,这对 JavaScript 优化器来说是个很大的问题。既然 eval()
不能被 JavaScript 解释器分析和优化,如果给 eval()
定义了一个别名,然后用别名来调用它,JavaScript 解释器会怎么工作?为了简化 JavaScript 解释器的实现,ECMAScript 3 标准规定了任何解释器都不允许对 eval()
赋予别名,如果这么做的话,会抛出 EvalError
异常。
ECMAScript 5 反对使用 EvalError
,但是规范了 eval()
的行为,直接调用 eval()
时,总是在调用它的上下文作用域内执行,其他间接调用则使用全局对象作为上下文作用域,并且无法读、写、定义局部变量和函数:
严格 eval
ECMAScript 严格模式对 eval()
函数的调用施加了更多的限制。在严格模式下,eval
执行的代码段可以查询或更改局部变量,但不能在局部作用域定义新的变量或函数,此外,还将 eval
作为保留字,不能用一个别名来覆盖,而且变量名、函数名、函数参数或异常捕获参数都不能取名「eval」。
No Comments