Je cherche un truc à ce sujet. Je sais comment appeler une fonction dynamique et arbitraire en JavaScript, en transmettant des paramètres spécifiques, par exemple:
function mainfunc(func, par1, par2){
window[func](par1, par2);
}
function calledfunc(par1, par2){
// Do stuff here
}
mainfunc('calledfunc', 'hello', 'bye');
Je sais comment transmettre des paramètres facultatifs et illimités à l'aide de la collection arguments
à l'intérieur de mainfunc
, mais je ne vois pas comment envoyer un nombre arbitraire de paramètres à mainfunc
à envoyer à calledfunc
dynamiquement; comment puis-je accomplir quelque chose comme cela, mais avec un nombre quelconque d'arguments optionnels (sans utiliser ce vilain 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');
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 cela serait beaucoup plus utile avec un léger tweak: -
function mainfunc (func){
this[func].apply(this, Array.prototype.slice.call(arguments, 1));
}
Cela fonctionnera en dehors du navigateur (this
par défaut dans l'espace global). L'utilisation de call on 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");
Votre code ne fonctionne que pour les fonctions globales, c.-à-d. membres de l'objet window
. Pour l'utiliser avec des fonctions arbitraires, transmettez la fonction elle-même à la place de son nom en tant que 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"
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);
}
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 la fonction et tous les autres sont utilisés comme arguments de la fonction appelée ...
Nous pouvons utiliser la méthode shift
pour renvoyer puis supprimer la première valeur du tableau d'arguments. Notez que nous l'appelons depuis le prototype Array puisque, à proprement parler, 'arguments' n'est pas un tableau réel et n'hérite donc pas de la méthode shift
comme le ferait un tableau normal.
Vous pouvez également appeler la méthode shift comme ceci:
[].shift.call(arguments);
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 soit déjà attachée à un objet "window".
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);
}
}
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();
}
}
}
});
};