Написание функции с переменным числом входных аргументов

#javascript

#javascript

Вопрос:

У меня есть функция javascript, количество входных аргументов которой неизвестно (имеет переменное количество аргументов), и у нее также есть аргумент словаря ввода, называемый аргументом «kwargs», который может иметь некоторые другие аргументы как (ключ, значение), например:

 function plot( data, kwargs={}){
}
 

Я хочу получить как «имя», так и «значение» аргументов в теле функции, когда я вызываю функцию с несколькими аргументами. Предположим, что я хочу вызвать функцию следующим образом:

 plot(lines, xlabel="Project", 
        ylabel="Investor", 
        xfmt="%", xscale=100, yfmt="%.", yscale=100)
 

Я хочу получить «xlable», «Project», «ylabel», «Investor», «xfmt», «%» и так далее (возможно, больше аргументов) в определении функции.

Как я могу написать ‘plot’ function def?

Комментарии:

1. Javascript не имеет именованных аргументов…

Ответ №1:

 function plot( data, kwargs={},...restArguments){
                                                }
 

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

Ответ №2:

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

Вы можете:

  1. Используйте словарь в качестве аргумента. Это позволит вам получить доступ к «аргументам» по их имени свойства.
    Однако для этого потребуется, чтобы вызывающий объект передавал объект, который потенциально создается при каждом вызове функции, что дает вашей программе некоторые дополнительные накладные расходы.
  2. Используйте arguments объект. Это работает для каждой версии ECMAScript.
    Однако вам придется обращаться к нему со смещением, равным количеству именованных параметров.
  3. Используйте синтаксис параметра Rest. Это работает с ES6 и рекомендуется по arguments сравнению с -подходом.

Обратите внимание, что без некоторого рефакторинга вы не сможете использовать подходы 2 и 3.

Использование dicionary

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

Это сделало бы это:

 function aFunc(aVar, anotherVar, aThirdVar) {
  console.log(aVar, anotherVar, aThirdVar);
}
 

Для этого:

 function aFunc(data) {
  console.log(data.aVar, data.anotherVar, data.aThirdVar);
}
 

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

 aFunc({aVar: 5, anotherVar: 10, aThirdVar: 20}); // Works
// -- or --
// Note the un-ordered properties
aFunc({aThirdVar: 20, aVar: 5, anotherVar: 10}); // Also works
 

Однако это связано со следующими проблемами:

  • Не интуитивно понятно, как вызываются функции
  • Определение резервных значений для свойств должно быть реализовано неродным способом.
    Этого можно добиться путем короткого замыкания следующим образом: data.var ||= 'fallback-value'; .
  • IDE не может статически проверять ваш код на наличие ошибок перед выполнением
  • Список параметров не полезен для разработчика
  • Самое важное: должен быть передан фактический объект. Скорее всего, это создано только для одного вызова, что приведет к ненужным накладным расходам программы при многократном вызове функции.

Преимущества использования этого подхода заключаются в:

  • «Параметры» определяются как свойства объекта. Это сохраняет лексическую область чистой (-er ).
    Однако это не должно быть фактором при принятии решения о том, какой подход выбрать.
  • Поскольку свойства объекта (по умолчанию) перечислимы, вы можете получить как имя свойства, так и его значение (возможно, это то, к чему вы стремитесь).

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

Поскольку arguments присутствует во всех версиях ECMAScript, я бы рекомендовал этот подход при стремлении к (совсем немного) обратной совместимости.

arguments присутствует в любом контексте выполнения функции, то есть как в объявлениях функций, так и в выражениях функций, однако не в выражениях функции со стрелкой (лямбда) (добавлено в ES6; для использования ES6 в любом случае рекомендуется использовать синтаксис параметра Rest).

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

Цитата из руководства Google по стилю JavaScript:

Функции, которые принимают переменное число аргументов, должны иметь последний аргумент с именем var_args . Вы не можете ссылаться на var_args в коде; используйте массив arguments .

Обратите внимание, что только потому, что Google делает это таким образом, не означает, что именно так нужно кодировать. Это просто руководство (!) по написанию кода при работе с кодом из Google.

Вот пример, следующий руководству по стилю Google:

 function aFunc(first, second, var_args) {
  console.log(first, second, arguments[2], arguments[3]);
}

aFunc(5, 10, 20); // => '5 10 20 undefined'
 

Использование параметра Rest-синтаксис

Синтаксис параметров Rest, а также выражение функции со стрелкой (лямбда) были введены в ES6.

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

Поскольку параметр Rest является фактическим массивом, можно использовать синтаксис Spread, а также любую функциональность, унаследованную Array , в отличие от arguments объекта.

Вот пример, аналогичный arguments объектному подходу, теперь вместо него используется синтаксис параметра Rest:

 function aFunc(first, second, ...rest) {
  console.log(first, second, rest[0], rest[1]);
}

aFunc(5, 10, 20);