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




параметра количеством (10)

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

Пример:

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

Answers

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

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

Когда другой разработчик просматривает ваш код, очень легко предположить, что эта функция не принимает параметры. Особенно, если этот разработчик не связан с ключевым словом arguments . Из-за этого неплохо следовать руководству по стилю и быть последовательным. Я буду использовать 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});

Какой из них выбрать?

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

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

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)

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

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

Конечно, просто используйте объект arguments .

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

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

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

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

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


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


Да, вот так:

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

load(1,2);

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

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

   // do stuff
}

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

  1. Это массив, а не объект, как аргументы. Это позволяет вам применять функции, такие как карта или сортировка напрямую.
  2. Он не включает все параметры, но только тот, который прошел от него. Например, функция (a, b, ... args) в этом случае args содержит аргумент 3 аргументам.length

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

function load(context) {

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

    var context = extend(defaults, context);

    // do stuff
}

Таким образом, если у вас есть много параметров, но необязательно устанавливать их при каждом вызове функции, вы можете просто указать нестандартные значения. Для метода 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];
}

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


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

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

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


'#' вернет пользователя в начало страницы, поэтому я обычно иду с void(0) .

javascript:; также ведет себя как javascript:void(0);





javascript function arguments argument-passing