Calling dynamic function with dynamic parameters i

2019-01-02 14:12发布

I'm looking for a trick about this. I know how to call a dynamic, arbitrary function in Javascript, passing specific parameters, something like this:

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

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

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

I know how to pass optional, unlimited parameters using arguments[] collection inside mainfunc, but, I can't figure how to send an arbitrary number of parameters to mainfunc to be sent to calledfunc dynamically; how can I accomplish something like this, but with any number of optional arguments (not using that ugly if-else)? :

function mainfunc (func){
    if(arguments.length == 3)
        window[func](arguments[1], arguments[2]);
    elseif(arguments.length == 4)
        window[func](arguments[1], arguments[2], arguments[3]);
    elseif(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');

10条回答
情到深处是孤独
2楼-- · 2019-01-02 14:44

You could use .apply()

You need to specify a this... I guess you could use the this within 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);
}
查看更多
十年一品温如言
3楼-- · 2019-01-02 14:51

Here's what you need:

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

The first argument is used as the function name and all of the remaining ones are used as arguments to the called function...

We're able to use the shift method to return and then delete the first value from the arguments array. Note that we've called it from the Array prototype since, strictly speaking, 'arguments' is not a real array and so doesn't inherit the shift method like a regular array would.


You can also call the shift method like this:

[].shift.call(arguments);
查看更多
旧人旧事旧时光
4楼-- · 2019-01-02 14:55

Your code only works for global functions, ie. members of the window object. To use it with arbitrary functions, pass the function itself instead of its name as a string:

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"
查看更多
无与为乐者.
5楼-- · 2019-01-02 14:56

Now I'm using this:

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();
                }
            }
        }
    });
};
查看更多
弹指情弦暗扣
6楼-- · 2019-01-02 14:56
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))

console: 3

查看更多
萌妹纸的霸气范
7楼-- · 2019-01-02 15:00

Couldn't you just pass the arguments array along?

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');
查看更多
登录 后发表回答