Как избежать повторения длинного списка параметров/аргументов в вызовах функций и определить их все в одном месте?

#javascript

Вопрос:

У меня есть следующий класс (пример псевдокода) :

     class Whatever {
    
      constructor(param1, param2, ... , param15) {
        
        this.someLongInitialTask1(param1, param2, ... , param15);
        
        this.someLongInitialTask2(param1, param2, ... , param15);
   
        // some other operations

      }
    

      someLongInitialTask1(param1, param2, ..., param15) {
         //here some operation to be performed only at inizialization
      }


      someLongInitialTask2(param1, param2, ..., param15) {
         //here some operation to be performed only at inizialization
      }

  }
 

Я хотел бы иметь возможность указывать в своем коде список параметров/аргументов param1, param2, ..., param15 только в 1 месте, вместо того, чтобы повторять их каждый раз, когда они мне нужны. Причина в том, чтобы сделать более надежный и поддерживаемый код и не забывать изменять параметры при различных множественных вызовах.

Как это возможно сделать?

Я не хочу, чтобы эти параметры были каким-то полем/свойством класса, потому что они полезны только тогда, когда класс изначально создан и нет необходимости «запоминать» их внутри объекта (нет необходимости назначать их полям объекта).

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

1. У вас слишком много параметров (см., например, рефакторинг.guru/запахи/длинный список параметров ). Может быть, они должны быть в одном объекте/массиве или в нескольких? Может быть, они должны быть вараргами ...params (которые упаковывали бы их в массив)?

2. почему у одного должно быть 100 параметров?

3. @jonrsharpe Спасибо тебе. Это был всего лишь пример псевдокода. На самом деле у меня нет 100 параметров, но это было просто для того, чтобы передать идею какого-то длинного списка (например, 10 или около того, в любом случае неудобно поддерживать).

4. Если это «неудобно поддерживать», это относится к категории нуждающихся в рефакторинге (15 и 100-это больше, чем обычно рекомендуемые 3-4). Более репрезентативный пример может помочь людям сделать более конкретные предложения.

5. Вместо этого передать объект? На самом деле вы ничего не можете сделать, чтобы создать именованные параметры, которые вы можете повторно использовать на месте. Возможно, более конкретный пример мог бы пролить свет на вашу реальную проблему.

Ответ №1:

Используйте ... синтаксис оператора распространения для этого:

 class Whatever {

  constructor() {
    this.someLongInitialTask(...arguments);
  }
 

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

1. Единственная проблема с этим заключается в том, что если вы разработчик, который собирается использовать это, вы знаете, что передать. Я надеюсь, что есть хорошая документация по использованию. 🙂

2. @epascarello Ну, это не то, о чем просит ОП. И я согласен, что конструктор и следующие функции делают слишком много, или эти параметры должны быть в виде ассоциативного массива.

3. @ Justinas хорошо, похоже, вы предлагаете просто создать ассоциативный массив, описывающий начальное состояние моего объекта, содержащий все необходимые мне параметры.

4. Да, именно так вы обычно обрабатываете значения конфигурации: var config = $.extend(defaultConfig, userConfig)

Ответ №2:

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

 class Whatever {
  constructor(...params) {
    this.someLongInitialTask(...params);
  }

  someLongInitialTask(...params) {
    const [param1] = params;
    console.log(param1);
    this.someLongInitialTask2(...params);
  }
  
  someLongInitialTask2(...params) {
    const [param1, param2, param3] = params;
    console.log(param1, param2, param3);
  }
}

new Whatever(1,2,3); 

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

1. Спасибо. Мне нравится передача с помощью этого оператора, но таким образом мне все равно нужно повторять список аргументов в различных вызовах someLongInitialTask1, someLongInitialTask2, … правильно ? Есть ли способ указать это только один раз ?

2. Вы можете сделать то же самое для someLongInitialTask2 etc. И если вы все еще хотите иметь доступ к заднице param1, param2 , вы можете уничтожить и это тоже. Я обновил свой ответ, чтобы показать это, например, someLongInitialTask интересуется только параметром 1, поэтому я только разрушаю его, но передаю все параметры в someLongInitialTask2..