Методы параметризации против глобальных переменных

10

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

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

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

Позвольте мне объяснить себя:

functionA(){
   x = something
   functionB(x)
}
functionB(x){
   functionC(x)
}
functionC(x){
   finallyDoSomethingWithX(x)
}
finallyDoSomethingWithX(x){
  x += 1 //Very dummy example ignoring pass by value, not reference.
}

Заменяется:

globalX;
functionA(){
   globalX = something
   functionB()
}
...
...
...
finallyDoSomethingWithX(){
   globalX += 1
}

Я чувствую, что второй способ дает столько свободы программированию, потому что параметры могут накапливаться легко, а также иногда могут быть очень ограничены, когда код должен быть повторно использован, но в то же время я чувствую, что функция потеряет свою модульность, когда она связана с переменной. в глобальной среде, также теряя возможность многократного использования, когда, например, я хочу работать finallyDoSomethingWithXс другой переменной, отличной от tha globalX.

Я думаю, что это происходит со мной, потому что я на самом деле не использую шаблоны проектирования, потому что я программирую на Javascript, который для меня ощущается как язык «один сценарий имеет дело со всеми» для средних проектов.

Любые советы? узоры? Я могу быть более конкретным, если это необходимо.

AFP_555
источник
5
Как правило, если вы передаете переменные очень глубоко, вы неправильно разбили проблему. Что касается глобальных переменных, управляющих состоянием в других частях системы, избегайте этого, как чумы. Невозможно управлять в определенный момент, и вы обнаружите, что вещи ломаются случайно, потому что какое-то состояние видоизменяется функцией, которую вы не ожидали случайно.
mgw854
Избегайте этого, как чумы. Понял. Не могли бы вы подробнее рассказать о том, что «вы не правильно разбили проблему». Я понимаю общую идею, но я не могу придумать пример или что-то, чтобы действительно понять это.
AFP_555
2
Обычное средство, когда вы получаете многоуровневую передачу аргументов, - это создание объекта метода : объекта нового класса, методы которого соответствуют функциям, которые передают параметры. Параметры могут затем стать переменными, локальными для объекта, и его методам больше не нужно передавать значения.
Килиан Фот
@KilianFoth Спасибо. Не могли бы вы уточнить какой-нибудь код, чтобы я мог проверить ответ?
AFP_555
1
Подумайте о том, чтобы рассматривать структуру вашего кода JavaScript так же, как в других языках (например, в тех, которые используют «настоящие» классы). Некоторые полезные ссылки по этому связанному вопросу о SO: stackoverflow.com/questions/927651/…
Бен Коттрелл

Ответы:

7

Не используйте глобальные переменные.

Также не передавайте параметры в цепочки функций!

Это сложно, потому что вы не используете реальный пример. Но обычно будет лучший подход.

Допустим, у нас есть переменная пароля, которую мы должны использовать для вызова apis, inturn которой используются различными низкоуровневыми функциями.

Глобальный подход (псевдокод)

var pass;

function multiply(a,b) {
   return apiMultiply(pass,a,b);
}

Подход с передачей параметров

function multiply(a,b,pass) {
    return apiMultiply(pass,a,b);
}

Объектный подход

class math {
    var api;
    constructor(pass) {
        api = new api(pass);
    }

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}
Ewan
источник
Отлично. Этот проход не находится в глобальной среде, а также не является параметром для нескольких функций, так как он может быть взят из атрибутов объекта. Спасибо.
AFP_555
3

Избегайте глобалов, таких как чума.

Любой код может изменить глобальный. Таким образом, если у вас была цепочка A (x) -> B (x) -> C (x) -> ... -> Z (x), и вы храните x в глобальном X, и теперь у вас есть цепочка A- > B-> C -> ...-> Z, то на каждом шаге этой длинной цепочки или в полностью независимом коде кто-то может изменить X. И значение, которое использует Z, может полностью отличаться от того, которое A началось с.

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

gnasher729
источник
1
Полностью согласен. Если для решения вашей проблемы вы используете глобальные переменные, теперь у вас есть две проблемы.
Калеб Мауэр