При создании функции JavaScript с несколькими аргументами я всегда сталкиваюсь с этим выбором: передать список аргументов или передать объект параметров.
Например, я пишу функцию для отображения nodeList в массив:
function map(nodeList, callback, thisObject, fromIndex, toIndex){
...
}
Я мог бы вместо этого использовать это:
function map(options){
...
}
где options это объект:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
Какой из них рекомендуется? Существуют ли руководящие указания относительно того, когда использовать один против другого?
[Обновление] Похоже, что существует консенсус в пользу объекта параметров, поэтому я хотел бы добавить комментарий: одна из причин, по которой у меня возникло желание использовать список аргументов в моем случае, заключалась в том, чтобы поведение соответствовало JavaScript встроенный метод array.map.
Array.prototype.map
имеет простой API, который не должен вызывать недоумение у любого опытного программиста.Ответы:
Как и многие другие, я часто предпочитаю передавать функцию
options object
в функцию, а не передавать длинный список параметров, но это действительно зависит от точного контекста.Я использую читаемость кода в качестве лакмусовой бумажки.
Например, если у меня есть вызов этой функции:
Я думаю, что код вполне читабелен, и передача отдельных параметров - это нормально.
С другой стороны, есть функции с такими вызовами:
Абсолютно нечитабельно, если вы не сделаете некоторые исследования. С другой стороны, этот код хорошо читается:
Это больше искусство, чем наука, но если бы мне пришлось назвать практические правила:
Используйте параметр options, если:
источник
Несколько аргументов в основном для обязательных параметров. С ними все в порядке.
Если у вас есть дополнительные параметры, это становится сложным. Если один из них зависит от других, так что они имеют определенный порядок (например, четвертому нужен третий), вам все равно следует использовать несколько аргументов. Почти все нативные EcmaScript и DOM-методы работают следующим образом. Хорошим примером является
open
метод XMLHTTP-запросов , где последние 3 аргумента являются необязательными - правило похоже на «нет пароля без пользователя» (см. Также документы MDN ).Опциональные объекты пригодятся в двух случаях:
undefined
).В твоем случае я бы порекомендовал
map(nodeList, callback, options)
.nodelist
иcallback
являются обязательными, остальные три аргумента приходят только изредка и имеют разумные значения по умолчанию.Еще один пример
JSON.stringify
. Возможно, вы захотите использоватьspace
параметр без передачиreplacer
функции - тогда вам придется вызывать…, null, 4)
. Объект аргументов мог бы быть лучше, хотя на самом деле это не очень разумно только для двух параметров.источник
Лучше всего использовать подход «параметры как объект». Вам не нужно беспокоиться о порядке свойств, и есть большая гибкость в том, какие данные передаются (например, необязательные параметры)
Создание объекта также означает, что параметры могут быть легко использованы для нескольких функций:
источник
Я думаю, что если вы создаете экземпляр чего-либо или вызываете метод объекта, вы хотите использовать объект параметров. Если это функция, которая работает только с одним или двумя параметрами и возвращает значение, предпочтительным является список аргументов.
В некоторых случаях хорошо использовать оба. Если ваша функция имеет один или два обязательных параметра и несколько необязательных параметров, сделайте первые два обязательных параметра обязательными, а третий - хэшем необязательных параметров.
В вашем примере я бы сделал
map(nodeList, callback, options)
. Требуются нодлист и обратный вызов, довольно просто узнать, что происходит, просто прочитав вызов, и это похоже на существующие функции карты. Любые другие параметры могут быть переданы в качестве необязательного третьего параметра.источник
Ваш комментарий к вопросу:
Так почему бы не сделать это? (Примечание: это довольно сырой Javascript. Обычно я использую
default
хеш и обновляю его с помощью параметров, передаваемых с помощью Object.extend или JQuery.extend или аналогичных ...)Итак, теперь, поскольку теперь стало гораздо более очевидным, что является необязательным, а что нет, все они являются допустимым использованием функции:
источник
Возможно, я немного опоздал на вечеринку с этим ответом, но я искал мнения других разработчиков по этой самой теме и наткнулся на эту тему.
Я очень не согласен с большинством респондентов и придерживаюсь подхода «множественных аргументов». Моим главным аргументом является то, что он препятствует другим анти-шаблонам, таким как «мутирование и возврат объекта param» или «передача того же объекта param другим функциям». Я работал над базами кода, которые широко использовали этот анти-шаблон, и отладка кода, который делает это быстро, становится невозможной. Я думаю, что это очень эмпирическое правило для Javascript, поскольку Javascript не является строго типизированным и допускает такие произвольно структурированные объекты.
Мое личное мнение состоит в том, что разработчики должны быть явными при вызове функций, избегать передачи избыточных данных и избегать модификаций по ссылке. Дело не в том, что эти шаблоны не позволяют писать краткий, правильный код. Я просто чувствую, что вашему проекту намного легче впасть в плохую практику разработки.
Рассмотрим следующий ужасный код:
Этот тип требует не только более явной документации для определения намерения, но также оставляет место для неопределенных ошибок. Что делать, если разработчик изменяет
param1
вbar()
? Как вы думаете, сколько времени потребуется, чтобы просмотреть кодовую базу достаточного размера, чтобы это уловить? Следует признать, что этот пример немного неискренен, поскольку предполагает, что к этому моменту разработчики уже применили несколько анти-паттернов. Но это показывает, как передача объектов, содержащих параметры, дает больше места для ошибок и двусмысленности, требуя большей степени добросовестности и соблюдения правильности const.Просто мои два цента по этому вопросу!
источник
Это зависит.
Основываясь на моих наблюдениях за дизайном этих популярных библиотек, вот сценарии, которые мы должны использовать option object:
И сценарии использования списка параметров:
источник
Объект является более предпочтительным, потому что, если вы передаете объект, его легко расширить количество свойств в этих объектах, и вам не нужно следить за порядком, в котором были переданы ваши аргументы.
источник
Для функции, которая обычно использует некоторые предопределенные аргументы, лучше использовать опцию object. Противоположным примером будет что-то вроде функции, которая получает бесконечное количество аргументов, таких как: setCSS ({height: 100}, {width: 200}, {background: "# 000"}).
источник
Я бы посмотрел на большие проекты Javascript.
Такие вещи, как карта Google, вы часто увидите, что для экземпляров объектов требуются объекты, а функциям - параметры. Я думаю, что это связано с OPTION argumemnts.
Если вам нужны аргументы по умолчанию или необязательные аргументы, возможно, объект будет лучше, потому что он более гибкий Но если у вас нет нормальных функциональных аргументов, они более явные.
У Javascript тоже есть
arguments
объект. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/argumentsисточник