eval()函数的介绍
eval函数可以执行js代码字符串。eval是顶级函数,跟任何对象没有关系。eval的参数是一个字符串,如果这个字符串表示的是一个表达式,那么eval函数会对它进行求值计算。如果eval的参数不是字符串,eval会原样返回。
|
eval直接调用执行js代码,会根据当前上下文环境执行代码,也就说直接调用eval,比如在函数内调用,那么js代码字符串中的变量会成为函数的局部变量。而间接调用eval执行js代码,会是在全局环境上下文中执行代码。这个很有用。
|
而间接调用eval的时候,我们要重新定义一个变量不太方便,所以通常我们采用window.eval()来实现间接调用eval的作用,使得js代码在全局作用域中执行,这样才跟我们的静态js代码效果一样。
像下面这样子调用eval:
|
但是呢,虽然ES规范中是这么定义的,但是在IE8-的低版本浏览器中,并没有按照这样实现,在IE8-中,上面两种eval间接调用的方式都不能使得代码中全局作用域中执行,它仍然和eval的直接调用的效果是一样的。
那么,在IE8-中是不是就没有办法在全局作用域中执行动态js代码了呢?
window.execScript
of course no,在IE中还有另一个跟eval相似的方法用来执行js代码字符串,它就是window.execScript方法。window.execScript方法永远是在全局作用域中执行js代码字符串,所以兼容性的eval代码如下:
|
并且呢,在IE8-的浏览器中的eval函数有一些bug问题,所以选择window.execScript来处理IE是最佳选择。
eval 和 execScript的js引擎
文章写到上面,其实eval的使用以及介绍的差不多了,你从百度上搜索也就能找到上面那些介绍了。但是我们实际应用中eval的理解的需求比这一个要多。
其实呢,eval也好,execScript是启动js引擎来执行js代码字符串的。所以eval 或者execScript同样拥有变量悬置的特性。
像下面这段代码:
|
无论是浏览器自己启动的js引擎还是通过eval,execScript启动的js引擎,他们的执行中的代码都会进行变量悬置,实际过程如下:
|
由于js引擎进行了变量悬置的处理,所以代码不会报错,输出的结果会是:c:undefined,这个结果结合浏览器处理过后的代码很好理解。
eval 不只可以执行简单的js表达式,它使用的就是浏览器自身的js引擎,所以我们正常写作浏览器中的js代码,都可以在eval函数中执行。
例如:
|
像上面的代码,我们通过eval函数一样可以执行的,其中使用了jquery的入口函数,只要页面中引入了jquery,那么在eval中的js代码字符串,一样可以使用jquery库。而通过eval的这种特性,我们可以把框架页面中的iframe去掉,而通过ajax获取页面的字符串,对其中的js通过eval执行,就可正常执行。
而在实际应用中,如果我们的系统是像上面这样用iframe实现的,现在要想去除iframe,那么通过ajax获取页面字符串,之后用eval函数执行其中的js代码,就可以实现快速的转换。而采用eval的方法的弊端就是,会在顶层window对象上添加了很多多余无用的代码,不利于页面的优化,但是它确是一个简便的权宜实现方式。
并且eval函数中有了jquery库后,使用的频率就更少了,jquery确实很强大,jquery的html()方法设置innerHTML代码,它内部对其中的js代码字符串进行了eval处理,并且就连外链script标签也进行了处理。所以如果对eval还是理解不清,那么就用jquery的html()方法来代劳吧。
eval 结语
eval函数功能很强大,但是权限太大,是一个危险的函数,如非必要,尽量不要使用eval函数,以免被别有用心的人利用,执行一些危险的代码。但是了解掌握eval函数还是必要的,在一些特殊情况下,还是有eval的用武之地的。