2012-04-27 112 views
0

我有一个方法的名称作为JavaScript变量的字符串,我想获得它的调用的结果变量:摆脱EVAL

var myMethod = "methodToBeCalled"; 
var result; 
eval("result = "+myMethod+"();") 

这工作,也没有问题。但是这个代码对于Google Closure编译器来说是不可接受的。我如何修改它以使用它?谢谢!

编辑:

似乎提出的解决方案时,该方法的名称是一些物体的内部不起作用,例如:假设你是不是在某些嵌套范围

var myFunction = function() { return "foo!" } 
var myObject = { 
    itsMethod: function() { return "foo!" } 
}; 
... 
var fstMethodToCall = "myFunction" 
var sndMethodToCall = "myObject.itsMethod"; 
... 
window[fstMethodToCall](); // foo! 
window[sndMethodToCall](); // undefined 

回答

2

样,试试:

var result = window['methodToBeCalled'](); 

var myMethod = 'methodToBeCalled'; 
var result = window[myMethod](); 

执行基于字符串指定任意深度的任意功能,而不是执行EVAL:

var SomeObject = { 
    level1: { 
     level2: { 
      someFunc: function() { 
       console.log('hello'); 
      } 
     } 
    } 
}; 

var target = 'SomeObject.level1.level2.someFunc'; 

var obj; 
var split = target.split('.'); 
for (var i = 0; i < split.length; i++) { 
    obj = (obj || window)[split[i]]; 
} 

obj(); 
+0

又是怎么回事窗口[ “SomeObject.itsMethod”] - 它似乎不起作用? – 2012-04-27 17:40:31

+0

@Vojtěch假设'SomeObject.itsMethod'为顶级功能的字符串值的名称,尝试窗口[SomeObject.itsMethod](); – Matt 2012-04-27 17:41:48

+0

我的意思是'var Object = {itsMethod:function(){...}}; var call =“Object.itsMethod”;窗口[call]();' – 2012-04-27 17:43:31

2

您可以使用索引符号:

result = window[myMethod](); 
1

的关闭编译器不禁止' eval',如果您发现方便,您可以继续使用它,但您必须了解编译器不会理解您的eval语句中发生了什么,并假设您的eval是“安全的”:

function f(x, y) { 
    alert(eval("y")); // fails: hidden reference to "y" 
    alert(eval('"'+x+'"')); // might be valid 
} 
f('me', 'you'); 

当编译器优化此函数时,它会尝试删除“y”并重命名剩余参数。这将使第一个评估失败,因为“y”不再存在。第二个评估会正确显示警报“我”。因此,与简单的优化

,你可以使用eval引用全局变量和对象属性,因为这些不重命名或删除(但不是本地的)。

凭借先进的优化,这是有点麻烦,因为编译器尝试删除和重命名全局和局部变量。所以你需要导出你需要保存的值。这也是真实的,如果你使用一个字符串来尝试通过其他方式来引用一个名字:

var methodName = "myMethod"; 
(window[methodName])() 

var methodName = "myMethod"; 
eval(methodName+"()") 

编译器根本不会尝试,以确定是否“方法名”是一个参考到一个功能。下面是一个简单的一种先进模式输出的例子:

window['myMethod'] = myMethod; 

的分配做了两两件事:它保留了myMethod的功能,如果它否则将被移除,它通过使用其分配给一个属性赋予它一个固定的名字串。如果您确实需要引用本地值,则需要稍微复杂一些,并使用Function构造函数。“F” 从我的第一个例子中的定义,可以EVAL当地人:

var f = new Function("x", "y", "alert(eval('y')); alert(eval('\"' + x + '\"'));"); 

您可能会发现此页面有用:

https://developers.google.com/closure/compiler/docs/limitations