Стандартный способ создания функций и передачи параметров — просто объявить имя функции и перечислить параметры в скобках:
function foo(param) { // do something }
Это работает хорошо, и в такой функции нет абсолютно ничего плохого.
Однако, когда мы передаем больше параметров в нашу функцию и/или начинаем добавлять необязательные параметры, это может стать неудобным в использовании:
function bar (param1, param2, param3, optionalParam1 = true) { // do something }
Прежде всего, мы должны помнить порядок параметров. Очевидно, что все современные IDE немного нам помогут. Тем не менее, это все еще сбивает с толку, когда мы просто смотрим на код:
zed(true, false, 5);
Мы можем легко изменить все наши функции, чтобы они использовали объект options. Перепишем функциональную панель:
function bar (options) { const { param1, param2, param3, optionalParam1 = true } = options; // do something }
Здесь мы использовали деструктурирующее присваивание. В теории и на практике мы могли бы сделать это прямо внутри скобки:
function bar ({ param1, param2, param3, optionalParam1 = true }) { // do something }
Однако, когда мы проверим, как это отображается, например, в Visual Studio Code, мы увидим, что IntelliSense отображает это:
Мы видим сигнатуру функции со всеми параметрами, за которыми следуют те же параметры и их тип.
Поэтому, если мы используем деструктурирование перемещения на следующую строку и просто используем параметры в сигнатуре функции:
Ладно, это не похоже на улучшение… пока. Давайте просто добавим правильный JSDoc:
/** * Example function * * @param {Object} options Options object * @param {string} options.param1 First parameter description here * @param {string} options.param2 Second parameter description here * @param {number} options.param3 Third parameter description here * @param {boolean} [options.optionalParam1=true] Optional parameter */ function bar(options) { const { param1, param2, param3, optionalParam1 = true } = options; // do something }
Теперь давайте посмотрим на IntelliSense:
Это выглядит намного лучше.
Более того, если мы дадим нашим параметрам осмысленные имена, например:
function connect(options) { const { address, port, timeout = 100 } = options; // connect... }
Мы можем вызвать эту функцию, передав параметры как объект в любом порядке:
connect({ address: '1.1.1.1', timeout: 200, port: 5000 });
Кроме того, имя параметра сразу скажет нам, для чего это значение!
Этот метод хорошо работает с функциями, которым требуется несколько параметров. На самом деле нет смысла рефакторить существующий код и использовать параметры, когда есть только один или два параметра.
Пусть нас ведет здравый смысл и руководства по стилю (внутренние, внешние или просто хорошие практики). Если конкретная функция выглядит хорошо и легко понять, какие параметры она там использует, мы можем оставить ее.
Однако все остальные функции можно легко реорганизовать для использования объекта параметров.