Appel de la fonction dynamique avec des paramètres dynamiques en Javascript [dupliquer]
Cette question a déjà une réponse ici:
- Passage d'un tableau en tant que paramètre de fonction en JavaScript 9 réponses
- transmettre des arguments à une autre fonction javascript [dupliquer] 3 réponses
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');
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");
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"
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 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);
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".
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();
}
}
}
});
};
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
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');
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);
}