globalizm tej zmiennej to tylko połowa problemu, bo owszem, robiąc zmienną globalną wciskasz się z butami w globalną przestrzeń nazw i jeśli inna aplikacja będzie używała tej samej zmiennej, to może ci się posypać program. Ukrywając ją w domknięciu faktycznie ją ukrywasz.
Ale to tylko połowa problemu, bo dalej zostaje stan współdzielony ("shared mutable state is the root of all evil", ja to mówią).
Jeśli masz zmienną globalną, i jeśli każda funkcja zmienia tę zmienną kiedy chce i każda funkcja czyta tę zmienną kiedy chce, i wiele funkcji uzależnia logikę od tej ciągle zmieniającej się zmiennej, to będzie ci ciężko zapanować nad tym, co się dzieje w programie. Z perspektywy aplikacji to jest to samo, bo nawet jeśli masz tą zmienną schowaną przed innymi aplikacjami, to dla ciebie jest ona globalna.
Zmienne, które się nie zmieniają (stałe) są trochę lepsze, ale tylko trochę, bo dalej ileś funkcji będzie zależne od takiej zmiennej globalnej, co też może utrudnić potem jakiekolwiek przeróbki programu.
Czy należąłoby działać tak aby zmienna o nazwie JakasZmienna była
ukryta w bloku jakiejś funkcji, domknięcia czy może czegoś innego?
Jeśli możesz. Jednak nie zawsze się tak da, i czasem musisz przekazać jakieś wartości z jednej funkcji do drugiej. Wtedy masz do wyboru:
- tworzenie zmiennej globalnej, czyli jest to zło, z powodu, o którym pisałem
- przekazywanie wartości jako argumentów do funkcji albo zwracanie czegoś w postaci return - również jest to zło, ponieważ jeśli masz wiele funkcji i przekazujesz do każdej jakieś argument, czy pobierasz jakieś wartości z innych funkcji - to też bardzo łatwo ci się zrobi burdel w aplikacji, i możesz się nie połapać, która funkcja zależy od której.
**Czyli zawsze będziesz musiał zrobić jakieś zło. W zasadzie w każdej większej aplikacji czyni się "zło" po to, żeby coś osiągnąć dobrego. ** ;)
Pytanie tylko, w jakiej sytuacji co będzie lepsze? Najlepiej po prostu zastosować jakąś technikę do maximum.
Jak powszechnie wiadomo stosowanie zmiennych globalnych to zło.
czyli np. jeśli nie wiesz, dlaczego stosowanie zmiennych globalnych to zło, to powinieneś napisać program, który by stosował tylko zmienne globalne, i wtedy zobaczysz, że jest to do d**y.
Ale z drugiej strony warto też poprogramować odwrotnie - czyli nie masz żadnych zmiennych globalnych, tylko z setkę funkcji i wszystkie wartości podajesz jako argumenty do funkcji. I walają ci się zmienne lokalne po całej aplikacji. Cieżko w takiej sytuacji zapanować nad "big picture", załapać obraz tego, co się dzieje tak ogólnie w twojej aplikacji. Dobrym przykładem są aplikacje w AngularJS czy React, które przesyłają przez pół aplikacji jaką zmienną do kolejnych komponentów (dlatego powstały takie rzeczy jak Redux albo Mobx, które pozwalają na stosowanie w React zmiennych globalnych* ale w taki sposób, żeby zniwelować wady zmiennych globalnych. Bo używając takich bibliotek jak coś zmienisz to od razu wszystkie zależne komponenty będą wiedzieć, że coś zmieniłeś i się uaktualnią. Ale z drugiej strony te biblioteki też są do d**y, przynajmniej Redux, z Mobx nie korzystałem).
* czy raczej zmiennych reprezentujących "globalny mutowalny stan", bo sama zmienna nie musi być wcale globalna (bo może być np. wstrzykiwana do komponentów w magiczny sposób).
Maciej Cąderek