协慌网

登录 贡献 社区

当我的名字作为字符串时,如何执行 JavaScript 函数

我在 JavaScript 中将函数的名称作为字符串。如何将其转换为函数指针,以便稍后调用?

根据具体情况,我可能还需要将各种参数传递给方法。

一些函数可能采用namespace.namespace.function(args[...])

答案

除非你绝对没有其他选择否则不要使用eval

如前所述,使用这样的东西是最好的方法:

window["functionName"](arguments);

但是,这不适用于命名空间函数:

window["My.Namespace.functionName"](arguments); // fail

这是你怎么做的:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

为了使这更容易并提供一些灵活性,这里有一个方便的功能:

function executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

你会这样称呼它:

executeFunctionByName("My.Namespace.functionName", window, arguments);

注意,你可以传入你想要的任何上下文,所以这将与上面相同:

executeFunctionByName("Namespace.functionName", My, arguments);

只是觉得我发布了一个略有改动版的Jason Bunting 非常有用的功能

首先,我通过向slice()提供第二个参数来简化第一个语句。原始版本在 IE 以外的所有浏览器中都运行良好。

其次,我在 return 语句中用上下文替换了 ; 否则,当执行目标函数时, 总是指向窗口

function executeFunctionByName(functionName, context /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for (var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    return context[func].apply(context, args);
}

这个问题的答案告诉你如何做到这一点: Javascript 相当于 Python 的本地人()?

基本上,你可以说

window["foo"](arg1, arg2);

或许多其他人建议,你可以使用 eval:

eval(fname)(arg1, arg2);

虽然这是非常不安全的,除非你完全确定你正在评估什么。