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");

Как я могу использовать функцию "бесконечного" параметра точно так же?

Ответ 1

Функции могут обращаться к массивоподобному объекту, называемому 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. Slice также полезен, если вы хотите, чтобы ваш массив содержал только неименованные аргументы, которые были получены:

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

Ответ 2

Современный способ сделать это - использовать параметры отдыха:

function printArguments(...args) {
  args.forEach((arg, index) => {
    console.log('Argument ${index}:', arg);
  });
}

printArguments('hello', true, new Date());

Используя синтаксис ...args, все параметры сохраняются в массиве с именем args.

За исключением Internet Explorer, все браузеры уже отправляют эту функцию в своей новой версии.

Скрипт: https://jsfiddle.net/Lbf0stst/

Ответ 3

Вы можете использовать массив аргументов: 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.");