我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
我有一个JavaScript函数的名称作为字符串。如何将其转换为函数指针以便稍后调用?
根据具体情况,我可能还需要将各种参数传递到方法中。
一些函数可以采用namespace.namespace.function(args[…])的形式。
当前回答
所有答案都假设函数可以通过全局作用域(窗口)访问。然而,OP并没有做出这样的假设。
如果函数存在于局部作用域(即闭包)中,并且没有被其他局部对象引用,那么运气就不好了:你必须使用eval() AFAIK,参见 在javascript中动态调用局部函数
其他回答
这个其他问题的答案向您展示了如何做到这一点:Javascript相当于Python的locals()?
基本上,你可以说
window["foo"](arg1, arg2);
或者像其他人建议的那样,你可以使用eval:
eval(fname)(arg1, arg2);
虽然这是非常不安全的,除非你完全确定你在评估什么。
我忍不住要提到另一个技巧,如果你有一个未知数量的参数,这些参数也作为包含函数名的字符串的一部分被传递,那么这个技巧是有用的。例如:
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>元素。
也有一些非常有用的方法。
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
var arrayMaker = {
someProperty: 'some value here',
make: function (arg1, arg2) {
return [ this, arg1, arg2 ];
},
execute: function_name
};
你可以把你的函数名放在一个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;
}
}
谢谢你非常有用的回答。我在我的项目中使用了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 );