Appel de la fonction dynamique avec des paramètres dynamiques en Javascript [dupliquer]

Cette question a déjà une réponse ici:

Je cherche un truc à propos de cette. Je sais comment appeler une fonction dynamique et arbitraire en Javascript, en passant des paramètres spécifiques, quelque chose comme ceci:

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

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

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

Je sais comment passer des paramètres facultatifs et illimités en utilisant la collection arguments [] à l'intérieur de mainfunc , mais je ne peux pas comprendre comment envoyer un nombre arbitraire de paramètres à mainfunc à envoyer à calledfunc dynamiquement; Comment puis-je accomplir quelque chose comme ça, mais avec n'importe quel nombre d'arguments optionnels 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');
142
demandé sur Cœur 2009-03-24 12:51:35

10 réponses

Utilisez la méthode apply d'une fonction: -

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

Edit: Il me semble que ce serait beaucoup plus utile avec une légère tweak:-

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

Cela fonctionne en dehors du navigateur (this par défaut, l'espace mondial). L'utilisation de l'appel sur mainfunc fonctionnerait également: -

function target(a) {
    alert(a)
}

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

mainfunc("target", "Hello");

mainfunc.call(o, "target", "Hello");
174
répondu AnthonyWJones 2016-08-11 21:06:09

Votre code ne fonctionne que pour les fonctions globales, c'est-à-dire. membres de l'objet window. Pour l'utiliser avec des fonctions arbitraires, passez la fonction elle-même au lieu de son nom sous forme de chaîne:

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"
20
répondu Ferdinand Beyer 2009-03-24 10:16:58

Vous pouvez utiliser .apply()

, Vous devez spécifier un this... Je suppose que vous pouvez utiliser le this dans 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);
}
14
répondu Greg 2009-03-24 12:03:11

Voici ce dont vous avez besoin:

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

Le premier argument est utilisé comme nom de fonction et tous les autres sont utilisés comme arguments pour la fonction appelée...

Nous pouvons utiliser la méthode shift Pour renvoyer puis supprimer la première valeur du tableau arguments. Notez que nous l'avons appelé à partir du prototype de tableau car, à proprement parler, 'arguments' n'est pas un vrai tableau et n'hérite donc pas de la méthode shift comme le ferait un tableau régulier.


Vous pouvez aussi appelez la méthode shift comme ceci:

[].shift.call(arguments);
12
répondu James 2009-11-18 16:05:34

Le moyen le plus simple pourrait être:

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

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

En supposant que cette fonction cible est déjà attachée à un objet "window".

5
répondu lubosdz 2013-06-08 11:03:45

Si vous voulez passer avec" arguments " quelques autres, vous devez créer le tableau de tous les arguments ensemble, c'est-à-dire comme ceci:

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);
    }
}
3
répondu Pavel Křupala 2012-02-23 11:48:55

Maintenant, j'utilise ceci:

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();
                }
            }
        }
    });
};
0
répondu uzay95 2014-05-08 13:26:12
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

-2
répondu Ilshat Khamitov 2016-05-20 11:13:34

Ne pourriez-vous pas simplement passer le tableau 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');
-4
répondu kkyy 2009-03-24 09:55:54

Dans le cas où quelqu'un recherche toujours un appel de fonction dynamique avec des paramètres dynamiques -

callFunction("aaa('hello', 'world')");

    function callFunction(func) {
                try
                {
                    eval(func);
                }
                catch (e)
                { }
            }
    function aaa(a, b) {
                alert(a + ' ' + b);
            }
-5
répondu kma1975 2013-11-08 08:17:41