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

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

一些函数可以采用namespace.namespace.function(args[…])的形式。


当前回答

取决于你在哪里,你也可以使用:

this["funcname"]();
self["funcname"]();
window["funcname"]();
top["funcname"]();
globalThis["funcname"]();

或者,在nodejs中

global["funcname"]()

其他回答

不要使用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);

你只需要通过window[<方法名>]将字符串转换为指针。 例子:

var function_name = "string";
function_name = window[function_name];

现在你可以把它当做一个指针。

不使用eval('function()'),您可以使用new function(strName)创建一个新函数。下面的代码是使用FF, Chrome, IE测试的。

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

小心! !

在JavaScript中应该尽量避免通过字符串调用函数,原因有两个:

原因1:一些代码混淆器会破坏你的代码,因为它们会改变函数名,使字符串无效。

原因2:维护使用这种方法的代码要困难得多,因为定位字符串调用的方法的用法要困难得多。

我只是想发布一个稍微改变了的Jason Bunting非常有用的函数。

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

其次,我在return语句中用context替换了它;否则,在执行目标函数时,它总是指向window。

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);
}