eval

eval()主要用来解释执行由js代码组成的字符串。接收一个参数,如果参数不为字符串,直接返回传递的参数。如果参数是字符串,它就会将字符串当成js代码进行编译,编译失败会抛出SyntaxError异常,编译成功就执行这段代码(即传递的字符串作为一个单独的脚本是有语义的)。并返回最后一个表达式或语句的值,如果最后一个表达式或语句没有值,则返回undefined。

1、eval()使用调用它的变量作用域环境。即全局作用域环境中调用时,eval作用于全局变量和全局函数;局部变量作用域环境中调用时,就会作用于局部变量和局部函数。   

 1 /* 全局作用域 */
 2 var x = 1;
 3 eval("function fun() {return x+1;}");
 4 fun() //动行结果:2
 5 
 6 /* 局部作用域 */
 7 var x = 2;
 8 function fun2() {
 9     var x = 10;
10     eval("x += 2");
11     alert(x); // 12    
12 }
13 alert(x); // 2

 2、全局eval():为了让js解释器的实现更加简化,ES3标准规定了任何解释器都不允许对eval()赋予别名。如果eval()函数通过别名调用的话,则会抛出EvalError异常。实际上大多数得实现在通过别名调用时,eval()会将其字符串当成顶层的全局代码来执行。即使在函数中调用时,也不能修改函数中的局部变量,而会直接作用于全局变量或函数。

ES5是反对使用EvalError的,并且规范了eval的行为。当直接使用非限定的eval名称来调用eval()函数时,通常称为"直接eval"(direct eval)。直接调用eval()时,它总是在调用它的上下文作用域内执行。其它间接调用则使用全局对象作为其上下文作用域,并且无法读,写,定义局部变量和函数。看下面代码:

 1 var geval = eval;
 2 var x = "global",
 3     y = "global";
 4 function fun() {
 5     var x = "local";
 6     eval("x += ' changed';");
 7     return x;
 8 }
 9 
10 function gFun() {
11     var y = "local";
12     geval("y += ' changed';");
13     return y;
14 }
15 
16 console.log(fun(), x);   //local changed global
17 console.log(gFun(), y); //local global changed

ps:ie9之前的版本,当通过别名调用eval()时并不是全局eval(),仅仅将其当作局部的eval来调用。但IE定义execScript()的全局函数来完成全局eval的功能。与eval()不同的时,这个家伙总是返回null;

 3、严格eval():ES5严格模式,对eval()函数的行为施加了更多的限制,甚至对标识符eval的使用也添加了限制。在严格模式下调用eval()时,或者eval()扫行的代码段以"use strict"指令开始,这里的eval()是私有上下文环境中的局部eval。即在严格模式下,eval扫行的代码段可以查询或更改局部变量,但不能在局部作用域中定义新的变量或函数。

 

---摘自《JavaScript 权威指南》第6版

 

posted @ 2015-02-04 23:01  尘云  阅读(329)  评论(0编辑  收藏  举报