我在第五篇讲运算符的时候其实还漏了一个运算符,这个运算符是eval()。可能你会觉得奇怪,这个不是一个函数吗,怎么会是一个运算符。事实上,它的确是个函数,但是现在已经被当做一个运算符来用,所以这个东西可以说即是运算符也可以说是函数。
那么这个eval(0函数有什么用呢,在eval()里面可以编译代码,但是函数内的参数必须是字符串,如果不是则直接返回这个参数。如:
var x = "1 + 1" alert(eval(x)) var y = 1 + 1 alert(eval(y))虽然第一个和第二个都能返回结果2,但是第一个是在eval里面进行编译才能返回2,而第二个是直接返回y的结果,而y本来就是2。在eval()函数里,它会将JavaScript代码进行编译,如果编译失败则抛出语法错误异常。如果编译成功但是如果这个代码没有值的话,eval()最终返回的结果是underfined。如果字符串抛出一个异常,则这个异常将把该调用传递给eval()。
除此以外,eval()函数使用了调用它的变量作用域环境。也就是说,它查找变量的值和定义新变量和函数的操作和局部作用域中的代码完全一样。如:
function a() { eval("var x") x = 1 return x } alert(a()) alert(x)在这个函数里,eval()函数编译了变量x并且在这个a()函数的作用域里,所以下面的给x赋值并不会生成一个全局变量,所以第一个会输出x的值,而第二个会报错。需要注意的是,传递给eval(0函数的字符串必须在语法上是讲得通的,不能通过eval()函数随意粘贴任意代码片段。如:eval("return ;")这个是没有意义的。因为return只有在函数中才起作用。
在ECMAScript3中,任何解释器都不允许对eval()赋予别名,如果eval()函数通过别名调用的话,则会抛出一个EvalError异常。虽然如此,当直接使用非限定的“eval”名称来调用eval()函数,这个时候它则是使用全局对象作为其上下文作用域,并且无法读、写、定义局部变量和函数。如;
var a = eval var x = 'global' var y = 'global' function f() { var x = 'local' eval("x += 'changed'") return x } function g() { var y = 'local' a("y += 'changed'") return y } console.log(f(), x) console.log(g(), y)最后结果输出的是localchanged global和local globalchanged。在这里全局对象在局部函数的作用域内,但是g()函数返回的y却是local,所以用eval()间接调用全局对象在局部函数里是不会改变局部函数的变量。上面的代码也可以改写成这样:
// var a = eval var x = 'global' var y = 'global' function f() { var x = 'local' eval("x += 'changed'") return x } function g() { var y = 'local' // a("y += 'changed'") window.eval("y += 'changed'") return y } console.log(f(), x) console.log(g(), y)直接使用window.eval()方法使得更容易理解。如果想要在局部函数中使用全局变量,也可以这样写:
function a(){ window.eval("var x=1"); console.log(x); } a(); console.log(x);这样输出来的都是1。但其实实际开发中,比较少用到eval()函数,这个函数可以作为了解,用处并不大。有一些博客讲到用到它的地方,下面是该博客的链接,可以过去查看:http://blog.csdn.net/huangboxi/article/details/4983828