Variable Scope: Local Versus Global Explained
Cover photo by Ilya Pavlov on Unsplash
Global variables are convenient. I get it. Sometimes it feels like you’re fighting the language just to pass data down a few levels. But global state is often a trap that bites you later.
How variables behave
Local scope means a variable only lives inside the function or block where you created it. Once that block finishes, the memory is cleaned up. Global scope is the opposite. You define a variable at the top level, and every piece of your code can touch it.
Consider this code.
let globalCount = 0;
function increment() { globalCount++;}
function reset() { let localCount = 0; localCount++;}In the increment function, you can change globalCount. In reset, you create localCount which vanishes the moment the function finishes running. It sounds simple, but it creates huge problems as your app grows.
Why global is dangerous
I’ve seen plenty of projects turn into a nightmare because of shared state. If ten different functions can change one variable, tracking down a bug is impossible. You don’t know which function changed the value or when it happened.
“But why can’t I just use a global for my user session data? It’s so much easier than passing props!”
That’s a fair point, and honestly, I do this sometimes when I’m prototyping a small tool. However, ease of use isn’t the same as maintainability. Once you have a team, or once that app needs to do more than one thing at a time, globals lead to race conditions and unpredictable side effects.
Local scope is your best friend
I suggest sticking to local scope by default. If you need to share data, pass it as an argument to a function. (Yes, I know this gets tedious with deep component trees, but it makes your code testable.)
Local scope keeps your functions pure. When a function relies only on its inputs and creates its own internal variables, you can test it in isolation. You don’t need to set up the entire state of your application just to verify that a single calculation works.
A caveat on context
I should mention that my obsession with local scope is mostly about application logic. If you are writing low-level system code or working in embedded environments, you might have hardware constraints that force your hand. Even then, try to group those globals into a single configuration object instead of letting them float around as loose variables.
Keep variables close to where they are used. If you don’t need it outside the function, don’t put it in the global space. Your future self, who has to debug this code at 2 AM, will appreciate it.
Do you find yourself reaching for globals when the pressure is on? It happens to the best of us.