Javascript неизвестное количество аргументов - PullRequest
6 голосов
/ 22 июня 2011

в моем проекте я регистрирую разные функции (с разным количеством аргументов) в качестве слушателей ряда событий. Когда событие происходит, мне нужно запустить соответствующую функцию. Я получаю параметры для передачи в метод слушателя в виде массива, тогда как функция слушателя ожидает каждый отдельный аргумент. Итак, я делаю это так, но мне не нравится подход, и я хотел бы знать, есть ли элегантный способ сделать это,

function callListenerWithArgs(func, args){
        switch(args.length){
            case 1:
                func(args[0]);
                break;
            case 2:
                func(args[0], args[1]);
                break;
            case 3:
                func(args[0], args[1], args[2]);
                break;
            case 4:
                func(args[0], args[1], args[2], args[3]);
                break;
            default:
                func();
        }
    }

Ответы [ 5 ]

2 голосов
/ 22 июня 2011

Использовать .apply

func.apply(null, args)

Если вам нужно привязать к определенной области, вы можете передать другой аргумент для использования в качестве this внутри функции:

func.apply(scope, args);

Также нюанс JavaScript в том, что вы можете вызывать функции с неопределенными значениями. Поэтому небольшая подстройка к существующему коду будет работать в 95% всех случаев (это не предлагается в качестве решения, просто указав на это):

// will handle any number of args up to 7
function callListenerWithArgs(func, args){
    func(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}

Если ваш func определен как:

function foo(a, b, c){
}

вы получаете a, b, c, а также некоторые undefined значения, которые игнорируются. Как я уже говорил выше, это работает в 95% случаев. Это не сработает, если вы когда-либо проверите arguments.length в вызываемой функции, поскольку она всегда будет одинаковой, независимо от количества параметров, определяемых функцией.

1 голос
/ 22 июня 2011
func.apply(this, args);

См. здесь .

1 голос
/ 22 июня 2011

functionName.apply(thisScope, arguments) было бы более элегантно. Аргумент arguments должен быть массивом.

Вы можете построить массив как:

var args = [];

switch (arguments.length - 1) {
    case 0:
        break;
    case 1:
        args.push(arguments[1]);
        break;
    case 2:
        args.push(arguments[1], arguments[2]);
        break;
    case 3:
        args.push(arguments[1], arguments[2], arguments[3]);
        break;
    default:
        args = Array.prototype.slice.call(arguments, 1);
}

или, если массив уже собран, просто передайте его в качестве второго аргумента .apply

1 голос
/ 22 июня 2011

Попробуйте, используя function.apply

function callListenerWithArgs(func, args){
    func.apply(window, args);
}
0 голосов
/ 22 июня 2011

Вы можете получить количество аргументов функции:

var f = function ( ) { console.log(arguments.length); }
f( 2, 3 )  // > 2

Это позволяет вам реализовать вашу функцию func непосредственно на месте.

function func() {
  var nbArgs = arguments.length;
  // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...