我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
当前回答
最简单的方法是像has元素一样访问它
window.ClientSideValidations.forms.location_form
和
window.ClientSideValidations.forms['location_form']
其他回答
下面是我的Es6方法,它允许你调用你的函数的名字作为字符串或它的函数名,也允许你传递不同数量的参数给不同类型的函数:
function fnCall(fn, ...args) { let func = (typeof fn =="string")?window[fn]:fn; if (typeof func == "function") func(...args); else throw new Error(`${fn} is Not a function!`); } function example1(arg1){console.log(arg1)} function example2(arg1, arg2){console.log(arg1 + " and " + arg2)} function example3(){console.log("No arguments!")} fnCall("example1", "test_1"); fnCall("example2", "test_2", "test3"); fnCall(example3); fnCall("example4"); // should raise an error in console
人们一直说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非常有用的函数。
首先,我通过向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);
}
你只需要通过window[<方法名>]将字符串转换为指针。 例子:
var function_name = "string";
function_name = window[function_name];
现在你可以把它当做一个指针。
谢谢你非常有用的回答。我在我的项目中使用了Jason Bunting的功能。
我扩展了它,使用一个可选的超时,因为设置超时的正常方式不会工作。请看abhishekisnot的问题
function executeFunctionByName(functionName, context, timeout /*, args */ ) { var args = Array.prototype.slice.call(arguments, 3); var namespaces = functionName.split("."); var func = namespaces.pop(); for (var i = 0; i < namespaces.length; i++) { context = context[namespaces[i]]; } var timeoutID = setTimeout( function(){ context[func].apply(context, args)}, timeout ); return timeoutID; } var _very = { _deeply: { _defined: { _function: function(num1, num2) { console.log("Execution _very _deeply _defined _function : ", num1, num2); } } } } console.log('now wait') executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );