Javascript: бесконечные параметры для функции?

В Chrome, когда я набираю console.log в приведенном ниже:

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");

... он печатает правильно, без ошибок или предупреждений. Я добавил больше параметров, но он все равно распечатывает их правильно.

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");

Как я могу иметь «бесконечную» функцию параметра, подобную этой?


person auroranil    schedule 18.02.2012    source источник


Ответы (3)


Функции могут обращаться к массивоподобному объекту с именем arguments, который содержит все аргументы, которые они получили.

function print_my_arguments(/**/){
    var args = arguments;
    for(var i=0; i<args.length; i++){
        console.log(args[i]);
    }
};

И вы можете сделать обратное преобразование (вызвать функцию с заданным списком аргументов) с помощью метода apply:

// These are equivalent:
print_my_arguments(1,2,3);
print_my_arguments.apply(null, [1,2,3]);

// The first parameter to `apply` is the `this`.
// It is used when the function is a method.
foo.bar(1,2,3);
var f = foo.bar; f.apply(foo, [1,2,3]);

Некоторые важные моменты, на которые следует обратить внимание:

  1. arguments не является фактическим массивом и не имеет ни одного из обычных методов массива (срез, объединение и т. д.). Вы можете преобразовать его в массив с помощью следующей строки:

    var args = Array.prototype.slice.call(arguments);
    
  2. Срез также полезен, если вы хотите, чтобы ваш массив содержал только полученные безымянные аргументы:

    function foo(first_arg, second_arg /**/){
        var variadic_args = Array.prototype.slice.call(arguments, 2);
    }
    
  3. Не каждый браузер может обрабатывать сколь угодно большое количество параметров функции. В прошлый раз, когда я тестировал это, в Chrome и IE произошло переполнение стека после примерно 200 000 аргументов. Если ваша функция может принимать произвольно большое количество аргументов, рассмотрите вместо этого упаковку всех этих аргументов в обычный массив.

  4. Те /**/ комментарии, которые появляются в списках аргументов для моих примеров, не являются обязательными. Это просто соглашение о кодировании, которое я использую, чтобы отметить свои вариативные функции и отличить их от обычных функций.

    // A quick glance would suggest that this function receives no
    // parameters but actually it is a variadic function that gets
    // its parameters via the `arguments` object.
    function foo(){
        console.log(arguments.length);
    }
    
person hugomg    schedule 18.02.2012
comment
Отличный ответ, +1 за предостережения, я их не читал и запустил первый. - person Jacob Valenta; 27.12.2013
comment
Для всех, кто приедет сюда в текущем году или позже, имейте в виду, что остальные параметры теперь являются предпочтительным способом сделать это. См. ответ Феликса Эдельманна ниже. - person Stephen M Irving; 27.02.2020


Вы можете использовать массив аргументов: jsfiddle.net/kUnJ2/

function foo() {
    for (var i = 0; i < arguments.length; i++) {
        document.body.innerHTML += arguments[i];
    }
}


foo("There ", "are ", "as ", "much ", "arguments ", "as ", "you ", "want.");
person DynasteN    schedule 28.02.2014
comment
Это повтор предыдущего ответа. В будущем полезно, если вы сможете предоставить альтернативный ответ или повысить ценность существующих ответов. - person Martin; 01.03.2014