Javascript: «Бесконечные» параметры для функции? - PullRequest
33 голосов
/ 18 февраля 2012

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

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

Ответы [ 3 ]

51 голосов
/ 18 февраля 2012

Функции могут обращаться к объекту, похожему на массив, называемому 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);
    }
    
2 голосов
/ 03 мая 2018

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

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/

0 голосов
/ 28 февраля 2014

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