使用动态数量的参数调用动态函数[重复]
Posted
技术标签:
【中文标题】使用动态数量的参数调用动态函数[重复]【英文标题】:Calling dynamic function with dynamic number of parameters [duplicate] 【发布时间】:2010-10-15 04:08:05 【问题描述】:我正在寻找一个技巧。我知道如何在 javascript 中调用动态的任意函数,传递特定的参数,如下所示:
function mainfunc(func, par1, par2)
window[func](par1, par2);
function calledfunc(par1, par2)
// Do stuff here
mainfunc('calledfunc', 'hello', 'bye');
我知道如何使用mainfunc
中的arguments
集合传递可选的、无限制的参数,但是,我不知道如何将任意数量的参数发送到mainfunc
以动态发送到calledfunc
;我怎样才能完成这样的事情,但可以使用任意数量的可选参数(不使用那个丑陋的if
–else
)?
function mainfunc(func)
if(arguments.length == 3)
window[func](arguments[1], arguments[2]);
else if(arguments.length == 4)
window[func](arguments[1], arguments[2], arguments[3]);
else if(arguments.length == 5)
window[func](arguments[1], arguments[2], arguments[3], arguments[4]);
function calledfunc1(par1, par2)
// Do stuff here
function calledfunc2(par1, par2, par3)
// Do stuff here
mainfunc('calledfunc1', 'hello', 'bye');
mainfunc('calledfunc2', 'hello', 'bye', 'goodbye');
【问题讨论】:
apply()
的 php 等效项是 call_user_func_array()
。 phpjs.org/functions/call_user_func_array 解决方案也使用它。
【参考方案1】:
使用函数的apply方法:-
function mainfunc (func)
window[func].apply(null, Array.prototype.slice.call(arguments, 1));
编辑:在我看来,稍微调整一下会更有用:-
function mainfunc (func)
this[func].apply(this, Array.prototype.slice.call(arguments, 1));
这将在浏览器之外工作(this
默认为全局空间)。在 mainfunc 上使用 call 也可以:-
function target(a)
alert(a)
var o =
suffix: " World",
target: function(s) alert(s + this.suffix);
;
mainfunc("target", "Hello");
mainfunc.call(o, "target", "Hello");
【讨论】:
击败我 :) developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/… 获取更详细的文档 这是最合适的解决方案,但在参数中它会包含函数的名称(arguments[0]='func')。我可以使用除第一个参数之外的所有参数生成另一个数组,然后使用这个新数组,但是,还有其他不使用其他数组的解决方案吗? ARemesal,请参阅我的解决方案答案(使用第一个参数作为函数名) @ARemesal:糟糕,是的,忘记从参数中分割出 func 参数。查看我的编辑。 是的 AnthonyWJones,它相当于 JimmyP 的解决方案。感谢您的解决方案,我发现了一些很棒的技巧:)【参考方案2】:您的代码仅适用于全局函数,即。 window
对象的成员。要将其与任意函数一起使用,请将函数本身而不是其名称作为字符串传递:
function dispatch(fn, args)
fn = (typeof fn == "function") ? fn : window[fn]; // Allow fn to be a function object or the name of a global function
return fn.apply(this, args || []); // args is optional, use an empty array by default
function f1()
function f2()
var f = function() ;
dispatch(f, [1, 2, 3]);
dispatch(f1, ["foobar"]);
dispatch("f1", ["foobar"]);
f2(); // calls inner-function "f" in "f2"
dispatch("f", [1, 2, 3]); // doesn't work since "f" is local in "f2"
【讨论】:
这行得通,但你应该注意这不是所要求的【参考方案3】:你可以使用.apply()
你需要指定一个this
...我猜你可以在mainfunc
中使用this
。
function mainfunc (func)
var args = new Array();
for (var i = 1; i < arguments.length; i++)
args.push(arguments[i]);
window[func].apply(this, args);
【讨论】:
您不需要将“参数”转换为 REAL 数组。这有什么意义?没有这一步它就可以完美地工作...... 如果你想省略第一个参数,它是函数的名称,则不是。 那为什么不直接使用'shift'呢? (见我的回答) 我没有使用 shift,因为我认为 [].xxx.call 在 IE 中不起作用,但我现在无法重现错误。【参考方案4】:这是你需要的:
function mainfunc ()
window[Array.prototype.shift.call(arguments)].apply(null, arguments);
第一个参数用作函数名,其余的所有参数都用作被调用函数的参数...
我们可以使用shift
方法返回并删除参数数组中的第一个值。请注意,我们从 Array 原型中调用它,因为严格来说,“arguments”不是真正的数组,因此不会像常规数组那样继承 shift
方法。
你也可以这样调用 shift 方法:
[].shift.call(arguments);
【讨论】:
非常感谢 JimmyP,您的解决方案(在编辑后)与 AnthonyWJones 的解决方案等效,您给了我关于使用 Array.prototype 和 [] 的重要提示和解释。 奇怪,我确定我试过这个并且在 IE 中遇到了错误【参考方案5】:最简单的方法可能是:
var func='myDynamicFunction_'+myHandler;
var arg1 = 100, arg2 = 'abc';
window[func].apply(null,[arg1, arg2]);
假设,目标函数已经附加到一个“窗口”对象。
【讨论】:
【参考方案6】:如果你想传递一些其他的“参数”,你必须一起创建所有参数的数组,即像这样:
var Log =
log: function()
var args = ['myarg here'];
for(i=0; i<arguments.length; i++) args = args.concat(arguments[i]);
console.log.apply(this, args);
【讨论】:
【参考方案7】:现在我正在使用这个:
Dialoglar.Confirm = function (_title, _question, callback_OK)
var confirmArguments = arguments;
bootbox.dialog(
title: "<b>" + _title + "</b>",
message: _question,
buttons:
success:
label: "OK",
className: "btn-success",
callback: function ()
if (typeof(callback_OK) == "function") callback_OK.apply(this,Array.prototype.slice.call(confirmArguments, 3));
,
danger:
label: "Cancel",
className: "btn-danger",
callback: function ()
$(this).hide();
);
;
【讨论】:
【参考方案8】:function a(a, b)
return a + b
;
function call_a()
return a.apply(a, Array.prototype.slice.call(arguments, 0));
console.log(call_a(1, 2))
控制台:3
【讨论】:
【参考方案9】:您不能直接传递arguments
数组吗?
function mainfunc (func)
// remove the first argument containing the function name
arguments.shift();
window[func].apply(null, arguments);
function calledfunc1(args)
// Do stuff here
function calledfunc2(args)
// Do stuff here
mainfunc('calledfunc1','hello','bye');
mainfunc('calledfunc2','hello','bye','goodbye');
【讨论】:
不,你不能,因为“arguments”不是一个数组,而是一个类似数组的对象,并且没有 shift() 成员。您需要将参数 1 复制到 arguments.length 到一个新数组并将该数组传递给 apply()。【参考方案10】:如果有人仍在寻找带有动态参数的动态函数调用 -
callFunction("aaa('hello', 'world')");
function callFunction(func)
try
eval(func);
catch (e)
function aaa(a, b)
alert(a + ' ' + b);
【讨论】:
不不不不。还有,没有。 在 2021 年,这将是热闹的 10 倍!以上是关于使用动态数量的参数调用动态函数[重复]的主要内容,如果未能解决你的问题,请参考以下文章
在参数中调用具有多个动态元组的 Python 函数 (geopy.distance.great_circle()) [重复]