eval(string) 和 eval(function) 的区别

5

我有一个Web应用程序,它使用jsonp将JavaScript代码返回给客户端。

这是我返回的代码(为了使其不可读):

com.xx.load('xx','var name="hguser";function data(x){console.info(x); }')

load函数中,我们会eval代码。然而,我们发现这样做会导致代码难以理解,也难以调试。因此,我想知道是否可以尝试以下方法:
com.xx.load('xx',function(){
  var name='hguser';
  function data(x){
    console.info(x); 
  }
});

那么,在load函数中,我们现在将会eval一个函数对象,而不是eval代码字符串。

这个可行吗?

它们的意思相同吗?


1
在这种情况下,我认为您可以使用 new Function('var name="hguser";function data(x){console.info(x); }') 代替 eval - elclanrs
+1,不知道为什么你被踩了。 - gdoron
我们使用 eval 而不是 new Function,因为返回的代码将访问在我的页面中定义的一些变量。但我想知道你是否指的是这个:(new Function('.....'))();?因为 eval 会立即执行代码。 - hguser
在第二种方法中,您将评估函数结果,而不是函数本身,结果为未定义 - zb'
2个回答

1

当然可以。这就像在JavaScript中模拟动态作用域一样。需要注意以下几点:

  1. 你不能直接eval一个函数。你需要将其转换为字符串。使用eval(String(f))
  2. 给函数f一个名称。你不能做var g = eval(String(f))。使用函数名称。
  3. 要小心。函数f将访问所有本地变量。

例如:

eval(String(getAdder()));

alert(add(2, 3));

function getAdder() {
    return function add(a, b) {
        return a + b;
    };
}

您可以在此处查看演示:http://jsfiddle.net/5LXUf/

只是一个想法 - 不要评估函数对象,为什么不直接调用它呢?这将为您提供堆栈跟踪,并且更简单、更安全(函数将无法访问您的本地变量)。


实际上我们想要的就是你所说的:堆栈跟踪。因为如果我们在返回的jsonp中使用eval(string),就无法获取跟踪信息。 - hguser
@hguser - 上述代码将为您提供正确的堆栈跟踪。请参见演示(打开调试器):http://jsfiddle.net/5LXUf/1/ - Aadit M Shah

0
请查看以下简化的代码: 正如我在评论中所说,第二种方法不起作用,因为它返回函数结果。
var my_load=function(arg1,for_eval) {
     eval(for_eval);    
     data(1);
}


my_load('xx','var name="hguser";function data(x){console.info(x); }');

my_load('xx',function(){
  var name='hguser';
  function data(x){
    console.info(x); 
  }
});​

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接