我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
当前回答
下面是我最终为我的一个项目实现的一个健壮且可重用的解决方案。
一个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['myfunction'](arguments)
就像Jason Bunting说的,如果你的函数名包含一个对象,它就不会工作:
window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work
下面是我的函数版本,它将按名称执行所有函数(包括对象与否):
My = { 代码:{ 是:{ Nice:函数(a, b){警报(a + "," + b);} } } }; Guy = function(){alert('awesome');} 函数executeFunctionByName(str, args) { Var arr = str.split('.'); Var fn = window[arr[0]]; For (var I = 1;I < arrr .length;我+ +) {fn = fn[arr[i]];} fn。应用(窗口,args); } executeFunctionByName(“my.code.is。Nice ', ['arg1', 'arg2']); executeFunctionByName(“家伙”);
你可以把你的函数名放在一个Array对象中,然后调用每个函数对应的数组键来执行它,DEMO:
function captchaTest(msg){
let x = Math.floor(Math.random()*(21-1)) +1;
let y = Math.floor(Math.random()*(11-1)) +1;
let sum = function(){
return x+y;
}
let sub = function(){
if (y > x){
let m = y;
y = x;
x = m;
console.log(x,y,m,'--')
}
return x-y;
}
let mul = function(){
return x*y;
}
let OParr = [sum(), sub(), mul()];
let OP = Math.floor(Math.random()*OParr.length);
let s = OParr[OP]; //!!! HERE !!! is the call as array element
switch(OP){
case 0:
opra = '+';
break;
case 1:
opra = '━';
break;
default:
opra = '✖';
}
let msg2 = 'Answer the following question to continue:'
let p = prompt(msg+' '+msg2+'\n'+'What is the result of '+x+opra+y+' ?','')
console.log(s,p,OP)
if (s == p){
alert ('Wow, Correct Answer!')
return true;
}
else{
alert('Sorry, the answer is not correct!')
return false;
}
}
const myFnCollection = {
myFnStringName: function(args) {}
};
let fn = 'myFnStringName';
// 1. Recommended
if (typeof window[fn] === 'function') {
window[fn](args);
}
// 2. Recommended
if (typeof myFnCollection[fn] === 'function') {
myFnCollection[fn](args);
}
// 3. Eval is evil ;)
if (typeof eval(fn) === 'function') {
eval(fn)(args);
}
惊讶地看到没有提到setTimeout。
运行一个不带参数的函数:
var functionWithoutArguments = function(){
console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);
运行带参数的函数:
var functionWithArguments = function(arg1, arg2) {
console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");
运行深度命名空间函数:
var _very = {
_deeply: {
_defined: {
_function: function(num1, num2) {
console.log("Execution _very _deeply _defined _function : ", num1, num2);
}
}
}
}
setTimeout("_very._deeply._defined._function(40,50)", 0);
我忍不住要提到另一个技巧,如果你有一个未知数量的参数,这些参数也作为包含函数名的字符串的一部分被传递,那么这个技巧是有用的。例如:
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>元素。