Стандартный способ создания функций и передачи параметров — просто объявить имя функции и перечислить параметры в скобках:

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 });

Кроме того, имя параметра сразу скажет нам, для чего это значение!

Этот метод хорошо работает с функциями, которым требуется несколько параметров. На самом деле нет смысла рефакторить существующий код и использовать параметры, когда есть только один или два параметра.

Пусть нас ведет здравый смысл и руководства по стилю (внутренние, внешние или просто хорошие практики). Если конкретная функция выглядит хорошо и легко понять, какие параметры она там использует, мы можем оставить ее.

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