我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
当前回答
我忍不住要提到另一个技巧,如果你有一个未知数量的参数,这些参数也作为包含函数名的字符串的一部分被传递,那么这个技巧是有用的。例如:
Var annoyingstring = 'call_my_func(123, true, "blah")';
如果你的Javascript运行在HTML页面上,你所需要的只是一个看不见的链接;您可以向onclick属性传递一个字符串,然后调用click方法。
<a href="#" id="link_secret"><!——invisible——></a>
$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();
或者在运行时创建<a>元素。
其他回答
下面是我最终为我的一个项目实现的一个健壮且可重用的解决方案。
一个FunctionExecutor构造函数
用法:
let executor = new FunctionExecutor();
executor.addFunction(two)
executor.addFunction(three)
executor.execute("one");
executor.execute("three");
显然,在项目中,所有需要按名称调用的函数的添加都是通过循环完成的。
函数Executor:
function FunctionExecutor() {
this.functions = {};
this.addFunction = function (fn) {
let fnName = fn.name;
this.functions[fnName] = fn;
}
this.execute = function execute(fnName, ...args) {
if (fnName in this.functions && typeof this.functions[fnName] === "function") {
return this.functions[fnName](...args);
}
else {
console.log("could not find " + fnName + " function");
}
}
this.logFunctions = function () {
console.log(this.functions);
}
}
使用示例:
function two() {
console.log("two");
}
function three() {
console.log("three");
}
let executor = new FunctionExecutor();
executor.addFunction(two)
executor.addFunction(three)
executor.execute("one");
executor.execute("three");
如果你想用window["functionName"]调用一个对象的函数而不是全局函数。你可以这样做;
var myObject=new Object();
myObject["functionName"](arguments);
例子:
var now=new Date();
now["getFullYear"]()
人们一直说eval是危险和邪恶的,因为它可以运行任何任意的代码。然而,如果您使用白名单方法使用eval,假设您知道所有可能需要提前运行的函数名,那么eval就不再是安全问题,因为输入不再是任意的。白名单是一种良好且常用的安全模式。这里有一个例子:
函数runDynamicFn(fnName,…args) { //也可以从一个严格控制的配置 const allowedFnNames = ['fn1', 'ns1.ns2.]fn3”、“ns4.fn4 '); 返回allowedFnNames.includes(fnName) ?eval(fnName)(…args): undefined; } //测试函数: 函数fn1(a) { Console.log ('fn1 called with', a) } runDynamicFn(“警报(“有你!”)”) runDynamicFn(“fn1”、“foo”)
为了补充Jason Bunting的答案,如果你正在使用nodejs或其他东西(这在dom js中也有效),你可以使用this而不是window(记住:eval是邪恶的:
this['fun'+'ctionName']();
我只是想发布一个稍微改变了的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);
}