// eval 函数和new Function的上下文环境:
// eval()函数入口参数中指定的字符串总是被作为当前函数上下文中的语句来执行
// new Function() 中传入的字符串总是被作为一个全局的、匿名函数闭包中的语句行被执行
//
eval("var a = 'global';"); // 声明一个全局的变量a
var obj = {};
(function (){
this.func = function() {
eval("var a = 'internal';"); // 这里没有覆盖全局的变量a
console.log("internal func:"+a); // 这里打印的a的值为 internal
new Function("console.log('new Function:'+a);")(); // 这里打印的a的值为 global
window.eval("alert(a);"); // 这里在IE和Firefox中表现不同,IE中认为是internal,Firefox中认为是global
};
}).call(obj);
obj.func();
console.log("global:"+a); // 这里打印的a的值为 global
// 使用eval获取对象直接量的方法,如:
var aobj = eval("{'a':'A','b':'B'}");
这种写法是错误的,因为参数字符串没有被理解为一个对象,而是被理解为一个符合语句;然而作为一个符合语句,这里是有语法错误的,所以执行错误,正确的写法为:var aobj = eval("({'a':'A','b':'B'})");
不过在jscript中存在一个例外:函数直接量(这里指匿名函数)不能通过这种方式来获得,例:
var func = eval('(function(){})');
alert(typeof func); // 输出为undefined
这种情况下,可以用具名函数来得到,例:var func;
eval('function func(){}');
alert(typeof func); // 输出为 function
但是你可能遇到必须使用匿名函数的情况(不打算使用上例那样确定的函数名),这时就需要稍微复杂一些的代码(使用表达式运算),例:
// var func = eval('(function(){}).prototype.constructor');
// var func = eval('({$:function(){}}).$');
// var func = eval('[function(){}][0]');
...