If I have a website, that has product filters and such. If I store the value in a global variable instead of element value, or vice versa. Sure, namespace is an issue, but if its complex, it would be unlikely to get overwritten. I've read it bad to allow access to the variables so they can be changed. Isnt anything on the client accessible? Also I dont see the difference between someone changing my global variable value VS changing the input value. If I store GPS coordinates of my users location to display a map, and the user changes it, how else would I store a "previous" location and a "new" location so if A user wants to revert back, they can. As long as I validate my data when it hits the servers, whats really the issue? Any thoughts?
-
You only need to store information in an input field if you plan on sending it in a GET or POST request using a form element. Other than that, you can store whatever you want as JavaScript variables. – John Jan 06 '21 at 01:50
-
Most of the concern with Global Variables stems from large projects with multi-year implementations and team developers. I would advise against using a complex name just so it won’t “get overwritten”. Documentation, organization and don’t get into the mix of “Where did this variable come from?!” – S. Walker Jan 06 '21 at 01:51
1 Answers
I've read it bad to allow access to the variables so they can be changed. Isnt anything on the client accessible?
There are 2 issues here.
The most important one (usually) is code maintainability. When you have a large script, if you use global variables, name collision is a real possibility. Yes, you can use a complex variable name, but it's easier to read code when the code uses simple and accurate variable names.
Apart from collisions, having lots of variables available to use in a given block increases cognitive overhead. If a variable is only relevant to one particular section of the code, segregating the variable into only that section can make the code easier to understand at a glance. For example, one could replace
let isActive = false;
// 200 lines of code
button.addEventListener('click', () => {
isActive = !isActive;
alert('isActive is ' + isActive);
});
with
// 200 lines of code
(() => {
let isActive = false;
button.addEventListener('click', () => {
isActive = !isActive;
alert('isActive is ' + isActive);
});
})();
(or even better, use ES6 modules to constrain scope)
See this post for a long discussion on this topic.
The other issue is, as you mentioned, if a variable is global, the user can change it. Sometimes this is a problem. For example, if you have a game that keeps track of coins the user has collected, the user can just open the console and do window.coins = 1e9
(in the unlikely event that they know JS and care to examine the source code to figure out how to do such a thing). Putting the variable into an enclosed IIFE will make such a technique much more difficult to pull off - but not impossible.
Fundamentally, the client can choose to run whatever code they want - it's their machine. So, you do need server-side validation - as you say you're doing, which is good.
As long as I validate my data when it hits the servers, whats really the issue?
Aside from the maintainability problem, it probably isn't an issue to worry about, since very very few people know and care enough to patch code on others' websites (and even then - it's their own computer, so who cares?). Lots of websites use global variables. It may be inelegant, but it can still work perfectly fine (as long as anything important sent to the server is validated on the server too).

- 356,069
- 52
- 309
- 320
-
thats the first decent answer ive read thus far on the issue. every other post i've read looks like a copy paste out of a text book. if I use current input fields and their values to filter products for my users, how else do I actually achieve the "NEVER" store variables in inputs/globals? – Jan 06 '21 at 02:11
-
Just put all the JS into an IIFE. `(() => { const products = someBigArrayFromDatabase; input.addEventListener('change', () => { const productsToShow = products.filter(p => p.name.includes(input.value)); // etc` Or, even better, use ES6 modules on the backend and use Webpack to compile them all together into a single ` – CertainPerformance Jan 06 '21 at 02:14