Вызов динамической функции с динамическим числом параметров
Я ищу трюк по этому поводу. Я знаю, как вызывать динамическую, произвольную функцию в JavaScript, передавая конкретные параметры, что-то вроде этого:
function mainfunc(func, par1, par2){
window[func](par1, par2);
}
function calledfunc(par1, par2){
// Do stuff here
}
mainfunc('calledfunc', 'hello', 'bye');
Я знаю, как передавать необязательные, неограниченные параметры, используя коллекцию arguments
внутри mainfunc
, но я не могу понять, как отправить произвольное количество параметров в mainfunc
для динамической отправки в calledfunc
; как я могу сделать что-то подобное, но с любым количеством необязательных аргументов (без использования этого уродливого 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');
Ответы
Ответ 1
Используйте метод применения функции: -
function mainfunc (func){
window[func].apply(null, Array.prototype.slice.call(arguments, 1));
}
Изменить. Мне кажется, что это было бы намного более полезно с небольшим подстройкой: -
function mainfunc (func){
this[func].apply(this, Array.prototype.slice.call(arguments, 1));
}
Это будет работать за пределами браузера (this
по умолчанию для глобального пространства). Использование вызова на mainfunc также будет работать: -
function target(a) {
alert(a)
}
var o = {
suffix: " World",
target: function(s) { alert(s + this.suffix); }
};
mainfunc("target", "Hello");
mainfunc.call(o, "target", "Hello");
Ответ 2
Ваш код работает только для глобальных функций, т.е. членов объекта window
. Чтобы использовать его с произвольными функциями, передайте функцию непосредственно вместо ее имени в виде строки:
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"
Ответ 3
Вы можете использовать .apply()
Вам нужно указать this
... Я думаю, вы могли бы использовать this
внутри 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);
}
Ответ 4
Вот что вам нужно:
function mainfunc (){
window[Array.prototype.shift.call(arguments)].apply(null, arguments);
}
Первый аргумент используется как имя функции, а все остальные используются в качестве аргументов вызываемой функции...
Мы можем использовать метод shift
для возврата, а затем удалить первое значение из массива аргументов. Обратите внимание, что мы вызвали его из прототипа Array, поскольку, строго говоря, "аргументы" не являются реальным массивом и поэтому не наследуют метод shift
, как обычный массив.
Вы также можете вызвать метод сдвига следующим образом:
[].shift.call(arguments);
Ответ 5
Самый простой способ:
var func='myDynamicFunction_'+myHandler;
var arg1 = 100, arg2 = 'abc';
window[func].apply(null,[arg1, arg2]);
Предполагая, что целевая функция уже привязана к объекту "window".
Ответ 6
Если вы хотите передать "аргументы" нескольким другим, вам нужно создать массив всех аргументов вместе, например:
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);
}
}
Ответ 7
Теперь я использую это:
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();
}
}
}
});
};
Ответ 8
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))
Консоль : 3
Ответ 9
Не могли бы вы просто передать массив 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');
Ответ 10
Если кто-то все еще ищет динамический вызов функции с динамическими параметрами -
callFunction("aaa('hello', 'world')");
function callFunction(func) {
try
{
eval(func);
}
catch (e)
{ }
}
function aaa(a, b) {
alert(a + ' ' + b);
}