在Javascript中使用动态参数调用动态函数

Calling dynamic function with dynamic parameters in Javascript

本问题已经有最佳答案,请猛点这里访问。

我正在寻找一个关于这个的伎俩。 我知道如何在Javascript中调用动态的任意函数,传递特定的参数,如下所示:

1
2
3
4
5
6
7
8
9
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)?:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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');


使用函数的apply方法: -

1
2
3
function mainfunc (func){
    window[func].apply(null, Array.prototype.slice.call(arguments, 1));
}

编辑:对我来说,稍微调整一下这会更有用: -

1
2
3
function mainfunc (func){
    this[func].apply(this, Array.prototype.slice.call(arguments, 1));
}

这将在浏览器之外工作(this默认为全局空间)。在mainfunc上使用call也可以: -

1
2
3
4
5
6
7
8
9
10
11
12
function target(a) {
    alert(a)
}

var o = {
    suffix:" World",
    target: function(s) { alert(s + this.suffix); }
};

mainfunc("target","Hello");

mainfunc.call(o,"target","Hello");


您的代码仅适用于全局函数,即。 window对象的成员。要将它与任意函数一起使用,请将函数本身而不是其名称作为字符串传递:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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"


你可以使用.apply()

你需要指定一个this ......我猜你可以在mainfunc中使用this

1
2
3
4
5
6
7
8
function mainfunc (func)
{
    var args = new Array();
    for (var i = 1; i < arguments.length; i++)
        args.push(arguments[i]);

    window[func].apply(this, args);
}


这就是你需要的:

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

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

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

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

1
[].shift.call(arguments);


最简单的方法可能是:

1
2
3
4
var func='myDynamicFunction_'+myHandler;
var arg1 = 100, arg2 = 'abc';

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

假设,该目标函数已经附加到"窗口"对象。


如果你想传递一些"参数",你必须一起创建所有参数的数组,例如:

1
2
3
4
5
6
7
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);
    }
}


现在我用这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Dialoglar.Confirm = function (_title, _question, callback_OK) {
    var confirmArguments = arguments;
    bootbox.dialog({
        title:"" + _title +"",
        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();
                }
            }
        }
    });
};

1
2
3
4
5
6
7
8
9
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


难道你不能只传递arguments数组吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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');


如果有人仍在寻找带动态参数的动态函数调用 -

1
2
3
4
5
6
7
8
9
10
11
12
13
callFunction("aaa('hello', 'world')");

    function callFunction(func) {
                try
                {
                    eval(func);
                }
                catch (e)
                { }
            }
    function aaa(a, b) {
                alert(a + ' ' + b);
            }