我处理JavaScript代码以改进。 这里的想法是动态调用函数。
以下是要替换的代码:
//this.actionCallback return the name of the function to invoke
eval(this.actionCallback + "('testArgument')");
更换它的最佳方法是什么:
这样:
window[this.actionCallback]("testArgument");
或者这样:
var actionToCall = this.actionCallback+'("testArgument");';
var functionToInvoke = new Function(actionToCall);
functionToInvoke();
或者有更好的方法吗?
答案 0 :(得分:4)
第一种方法是一种更好的方法 - new Function(actionToCall)
只是伪装成eval。
答案 1 :(得分:1)
您提到的两种替代方案都与第一种不等同:
您的第一个选择要求函数名称是window
的成员(换句话说,在全局范围内定义)。在另一个范围内使用函数会导致此操作失败,但它不使用eval。 :)
你的第二个替代方法是使用Function()
构造函数创建一个函数对象,所以这也仅适用于在全局范围内声明的函数,因为a function defined by a Function constructor does not inherit any scope other than the global scope,并且如Jamie Wong所述回答,使用Function()构造函数仍被视为eval:(
这是一个应该像你的第一个一样工作的替代方案,但看起来稍好一点,但仍然使用eval。
eval(this.actionCallback)("testArgument");
但最好的方法是this.actionCallback
应该是一个真正的函数对象,而不仅仅是函数的名称,那么你可以调用:
this.actionCallback("testArgument");
答案 2 :(得分:0)
我建议使用window[this.actionCallback]("testArgument");
。
这样就没有eval
或匿名函数。你只是直接调用这个函数。
答案 3 :(得分:0)
在这种情况下,您可能不希望允许调用任意函数,而仅允许“动作”函数。 建立受支持的回调列表
actionCallbacks["doWork"] = doWork;
给他们打电话
actionCallbacks[this.actionCallback]("testArgument")
并捕获不存在的功能
答案 4 :(得分:0)
如果函数属于对象,则可以执行以下操作:
function run(func, object, args = []) {
object[func]().apply(object, args);
}
此外,这是替换eval的唯一(但不是很可靠)方法:
function evaluate(code) {
location.href = "javascript:" + code;
}
evaluate("alert(1)");