ECMAScript 语言中最强大的一个方法:eval()。eval() 方法就像是一个完整的 ECMAScript 解析器,它只接受一个参数,即要执行的 ECMAScript(或 JavaScript) 字符串。看下面的例子:
eval("alert('hi')");
这行代码的作用等价于下面这行代码:
alert("hi");
当解析器发现代码中调用 eval()方法时,它会将传入的参数当作实际的 ECMAScript 语句来解析, 然后把执行结果插入到原位置。通过 eval()执行的代码被认为是包含该次调用的执行环境的一部分, 因此被执行的代码具有与该执行环境相同的作用域链。这意味着通过 eval()执行的代码可以引用在包 含环境中定义的变量,举个例子:
var msg = "hello world";
eval("alert(msg)"); //"hello world"
可见,变量 msg 是在 eval()调用的环境之外定义的,但其中调用的 alert()仍然能够显示"hello world"。这是因为上面第二行代码最终被替换成了一行真正的代码。同样地,我们也可以在 eval() 调用中定义一个函数,然后再在该调用的外部代码中引用这个函数:
eval("function sayHi() { alert('hi'); }");
sayHi();
显然,函数 sayHi()是在 eval()内部定义的。但由于对 eval()的调用最终会被替换成定义函数 的实际代码,因此可以在下一行调用 sayHi()。对于变量也一样:
eval("var msg = 'hello world'; "); alert(msg); //"hello world"
在 eval()中创建的任何变量或函数都不会被提升,因为在解析代码的时候,它们被包含在一个字 符串中;它们只在 eval()执行的时候创建。 严格模式下,在外部访问不到 eval()中创建的任何变量或函数,因此前面两个例子都会导致错误。 同样,在严格模式下,为 eval 赋值也会导致错误:
"use strict"; eval = "hi"; //causes error
能够解释代码字符串的能力非常强大,但也非常危险。因此在使用 eval()时必 须极为谨慎,特别是在用它执行用户输入数据的情况下。否则,可能会有恶意用户输 入威胁你的站点或应用程序安全的代码(即所谓的代码注入)。