javascript中的eval是一个非常灵活,但是灵活是伴随着风险的.
一.下面我们来看看那使用eval声明变量的问题.
1 function test(x){ 2 eval("var a=x;"); 3 return a; 4 } 5 alert(test("hello"));
这个代码看起来还是比较简易的.
1 var q="全局的"; 2 function test(x){ 3 eval(x); 4 return q; 5 } 6 alert(test("var q='局部的';"));//局部的 7 alert(test("var z='局部的';"));//全部的
这段代码很脆弱,也不安全.因为它赋予了外部调用者能改变test函数内部作用域.
保证eval函数不影响外部作用域的一个简单方法是在一个明确的嵌套作用域中运行它.
1 var q="全局的"; 2 function test(x){ 3 (function(){eval(x);})(); 4 return q; 5 } 6 alert(test("var q='局部的';"));//局部的 7 alert(test("var z='局部的';"));//全部的
二.eval的直接调用和间接调用
//这是直接调用 var g="全局的"; function test(){ var x="局部的"; return eval("x"); } alert(test());//局部的
1 //这是间接调用 2 var g="全局的"; 3 function test(){ 4 var x="局部的"; 5 var f=eval; 6 return f("x"); 7 } 8 alert(test());
不提倡这种做法.<<Effective Javascript>>上有这种说法.但是在浏览器上测试的话,就是不通过.会出现报错现象.
1 /* 2 一种奇葩的eval间接调用方式. 3 */ 4 var g="全局的"; 5 function test(){ 6 var x="局部的"; 7 return (0,eval)("x");//是不是很奇葩的调用 8 } 9 //alert(test());//局部的
(0,eval)("x");是如何工作的呢?
数字0被求值但其值被忽略了,括号说执行的结果是eval函数.因此,(0,eval)的行为几乎与简单的eval函数表示完全一致.
单子这种间接的调用eval函数的方式性能更加好,速度更加的快.