我有一个方法的名称作为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
答案 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