使用动态数量的参数调用动态函数

IT技术 javascript function
2021-01-16 21:21:34

我正在寻找有关此的技巧。我知道如何在 JavaScript 中调用动态的任意函数,传递特定参数,如下所示:

function mainfunc(func, par1, par2){
    window[func](par1, par2);
}

function calledfunc(par1, par2){
    // Do stuff here
}

mainfunc('calledfunc', 'hello', 'bye');

我知道如何使用arguments里面集合传递可选的、无限制的参数mainfunc,但是,我无法弄清楚如何发送任意数量的mainfunccalledfunc动态发送的参数我怎样才能完成这样的事情,但有任意数量的可选参数(不使用那个丑陋的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');
6个回答

使用函数的 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");
ARemesal,请参阅我的解决方案答案(使用第一个参数作为函数名称)
2021-03-13 21:21:34
2021-03-15 21:21:34
是的 AnthonyWJones,它相当于 JimmyP 的解决方案。感谢您的解决方案,我发现了一些很棒的技巧:)
2021-03-27 21:21:34
这是最合适的解决方案,但在参数中它将包含函数的名称(参数 [0]='func')。我可以使用除第一个参数之外的所有参数生成另一个数组,然后使用这个新数组,但是,是否还有其他不使用其他数组的解决方案?
2021-04-01 21:21:34
@ARemesal:oop是的忘了从参数中切掉 func 参数。请参阅我的编辑。
2021-04-10 21:21:34

您的代码仅适用于全局函数,即。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"
这有效,但您应该注意这不是所要求的
2021-03-30 21:21:34

你可以用 .apply()

你需要指定一个this......我想你可以使用thisinside mainfunc

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 数组。这有什么意义?没有那一步它就可以完美运行......
2021-03-15 21:21:34
为什么不直接使用'shift'呢?(见我的回答)
2021-03-24 21:21:34
我没有使用 shift 是因为我认为 [].xxx.call 在 IE 中不起作用,但我现在无法重现该错误。
2021-03-26 21:21:34
如果您想省略第一个参数,即函数的名称,则不能。
2021-04-03 21:21:34

这是您需要的:

function mainfunc (){
    window[Array.prototype.shift.call(arguments)].apply(null, arguments);
}

第一个参数用作函数名称,其余所有参数用作被调用函数的参数...

我们可以使用该shift方法返回,然后从参数数组中删除第一个值。请注意,我们从 Array 原型中调用它,因为严格来说,'arguments' 不是真正的数组,因此不会shift像常规数组那样继承该方法。


你也可以像这样调用 shift 方法:

[].shift.call(arguments);
非常感谢 JimmyP,您的解决方案(编辑后)与 AnthonyWJones 的解决方案等效,并且您给了我关于使用 Array.prototype 和 [] 的重要提示和解释。
2021-03-12 21:21:34
奇怪,我确定我试过这个并且在 IE 中出现错误
2021-03-20 21:21:34

最简单的方法可能是:

var func='myDynamicFunction_'+myHandler;
var arg1 = 100, arg2 = 'abc';

window[func].apply(null,[arg1, arg2]);

假设,该目标函数已经附加到一个“窗口”对象。