Переменная JavaScript количество аргументов для функции

есть ли способ разрешить "неограниченные" vars для функции в JavaScript?

пример:

load(var1, var2, var3, var4, var5, etc...)
load(var1)

11 ответов


конечно, просто использовать


другой вариант-передать ваши аргументы в объекте контекста.

function load(context)
{
    // do whatever with context.name, context.address, etc
}

и использовать его в таком виде

load({name:'Ken',address:'secret',unused:true})

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


в последних браузерах вы можете принять переменное количество аргументов с этим синтаксисом:

function my_log(...args) {
     //args is an Array
     console.log(args);
     //You can pass this array as parameters to another function
     console.log(...args);
}

Я согласен с ответом Кена как наиболее динамичным, и мне нравится делать шаг вперед. Если это функция, которую вы вызываете несколько раз с разными аргументами - я использую дизайн Кена, но затем добавляю значения по умолчанию:

function load(context) {

    var defaults = {
        parameter1: defaultValue1,
        parameter2: defaultValue2,
        ...
    };

    var context = extend(defaults, context);

    // do stuff
}

таким образом, если у вас есть много параметров, но не обязательно, чтобы установить их при каждом вызове функции, вы можете просто указать номера по умолчанию. Для метода extend можно использовать метод extend jQuery ($.extend()), создайте свой собственный или используйте следующий:

function extend() {
    for (var i = 1; i < arguments.length; i++)
        for (var key in arguments[i])
            if (arguments[i].hasOwnProperty(key))
                arguments[0][key] = arguments[i][key];
    return arguments[0];
}

это объединит объект контекста со значениями по умолчанию и заполнит любые неопределенные значения в вашем объекте со значениями по умолчанию.


Да, вот так :

function load()
{
  var var0 = arguments[0];
  var var1 = arguments[1];
}

load(1,2);

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

если вы хотите вызвать другую функцию с теми же аргументами, используйте apply. Вы даже можете добавлять или удалять аргументы, конвертируя arguments в массив. Например, эта функция вставляет текст перед входом в консоли:

log() {
    let args = Array.prototype.slice.call(arguments);
    args = ['MyObjectName', this.id_].concat(args);
    console.log.apply(console, args);
}

хотя я в целом согласен с тем, что подход с именованными аргументами полезен и гибок (если вы не заботитесь о порядке, в этом случае аргументы проще всего), у меня есть опасения по поводу стоимости подхода mbeasley (используя значения по умолчанию и extends). Это крайняя сумма затрат для извлечения значений по умолчанию. Во-первых, значения по умолчанию, определенные внутри функции, поэтому они переписывается при каждом вызове. Во-вторых, вы можете легко считывать именованные значения и устанавливать значения по умолчанию время использования ||. Для получения этой информации нет необходимости создавать и объединять еще один новый объект.

function load(context) {
   var parameter1 = context.parameter1 || defaultValue1,
       parameter2 = context.parameter2 || defaultValue2;

   // do stuff
}

Это примерно столько же кода (может быть, немного больше), но должно быть частью стоимости выполнения.


предпочтительно использовать синтаксис параметра rest, как указал Рамаст.

function (a, b, ...args) {}

Я просто хочу добавить некоторые интересные свойства ...аргумент args

  1. это массив, а не объект, как аргументы. Это позволяет применять такие функции, как map или sort напрямую.
  2. он не включает в себя все параметры, но только один, переданный из него. Е. Г. функция (а, б, ...аргументы) в этом случае args содержит довод 3 к аргументы.длина

использовать arguments объект, когда внутри функции есть доступ ко всем переданным аргументам.


в то время как @roufamatic показал использование ключевого слова arguments, а @Ken показал отличный пример объекта для использования, я не чувствую, что действительно обратился к тому, что происходит в этом случае, и может запутать будущих читателей или привить плохую практику, поскольку явно не указывая, что функция/метод предназначена для использования переменного количества аргументов/параметров.

function varyArg () {
    return arguments[0] + arguments[1];
}

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

давайте явно заявим, что та же функция имеет переменные параметры:

function varyArg (var_args) {
    return arguments[0] + arguments[1];
}

параметр объекта VS var_args

могут быть случаи, когда объект необходим, поскольку это единственный одобренный и рассмотренный метод наилучшей практики карты данных. Ассоциативные массивы не одобряются и не поощряются.

SIDENOTE: ключевое слово arguments фактически возвращает объект, используя числа в качестве ключа. Прототипное наследование также является семейством объектов. См. конец ответа для правильного использования массива в JS

в этом случае мы также можем явно указать это. Примечание: это соглашение об именах не предоставляется Google, но является примером явного объявления типа param. Это важно, если вы ищете чтобы создать более строгий типизированный шаблон в коде.

function varyArg (args_obj) {
    return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});

какой выбрать?

это зависит от вашей функции и программы. Если, например, вы просто хотите вернуть базу значений в итерационном процессе по всем переданным аргументам, то, скорее всего, придерживайтесь аргументы ключевое слово. Если вам нужно определение ваших аргументов и сопоставление данных, то метод объекта-это путь. Давайте рассмотрим два примера и тогда мы закончили!

использование аргументов

function sumOfAll (var_args) {
    return arguments.reduce(function(a, b) {
        return a + b;
    }, 0);
}
sumOfAll(1,2,3); // returns 6

объект использования

function myObjArgs(args_obj) {
    // MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
    if (typeof args_obj !== "object") {
        return "Arguments passed must be in object form!";
    }

    return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old

доступ к массиву вместо объекта ("...args " параметр rest)

как упоминалось в верхней части ответа аргументы ключевое слово фактически возвращает объект. Из-за этого любой метод, который вы хотите использовать для массива, должен быть вызван. Пример:

Array.prototype.map.call(arguments, function (val, idx, arr) {});

чтобы избежать этого, используйте параметр rest:

function varyArgArr (...var_args) {
    return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5

имейте в виду, что передача объекта с именованными свойствами, как предложил Кен, добавляет стоимость выделения и освобождения временного объекта для каждого вызова. Передача обычных аргументов по значению или ссылке, как правило, будет наиболее эффективной. Для многих приложений, хотя производительность не критична, но для некоторых это может быть.