摆脱eval

时间:2012-04-27 17:30:15

标签: javascript eval google-closure-compiler

我有一个方法的名称作为javascript变量中的字符串,我想得到它调用变量的结果:

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

这有效,没有问题。但是这个代码对于Google Closure Compiler来说是不可接受的。如何修改它以使用它?谢谢!

编辑:

当方法的名称在某个对象内部时,似乎提议的解决方案不起作用,例如:

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

3 个答案:

答案 0 :(得分: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();

答案 1 :(得分:2)

您可以使用索引符号:

result = window[myMethod]();

答案 2 :(得分:1)

Closure Compiler没有禁止'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”并重命名retain参数。这将是第一个eval失败,因为“y”不再存在。第二个评估将正确显示警告“我”。

因此,使用SIMPLE优化,您可以使用eval来引用全局变量和对象属性,因为这些变量和对象属性不会被重命名或删除(而不是本地变量)。

使用ADVANCED优化,它有点棘手,因为编译器试图删除和重命名全局变量和局部变量。因此,您需要导出需要保留的值。如果您使用字符串尝试通过其他方式引用名称,也是如此:

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

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

编译器根本不会尝试确定“methodName”是否是对函数的引用。以下是ADVANCED模式导出的简单示例:

window['myMethod'] = myMethod;

赋值做了两件事:它保留了myMethod函数,否则它将被删除,并通过使用字符串将其赋值给属性来赋予它一个固定的名称。如果确实需要引用本地值,则需要使用函数构造函数。我的第一个例子中的“f”的定义,可以评估当地人:

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

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

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