2

I'm currently face with a problem where I have two modules that I call that need to be able to modify the same variable.
I decided to create a global variable called global.APP_NAME = {} and store the variables that I need in that.

But I have been reading that it is bad practice to use global variables. Why is it?

I am only creating one variable, that should not collide with anything else because it is the name of my application.

C1D
  • 3,034
  • 2
  • 21
  • 20
  • In general is a bad practice to overload the global scope. One variable is ok but it'll be better if you'll have your variables into a namespace like global.myProject = { ... } – Aurelio De Rosa Sep 05 '13 at 11:33
  • 2
    Keeping everything as local as possible avoids collisions, but also improves readability of code as you don't have to leave the local scope all the time when trying to understand it. – Ingo Bürk Sep 05 '13 at 11:36
  • This issue is not related to any specific language or platform, it's true for all languages. Don't limit your research to just node.js. For example, [this question](http://codereview.stackexchange.com/questions/29130/global-variables-is-this-code-good-practice) is asking pretty much the same thing for C++, and the answers are all basically just as relevant for your case. – Spudley Sep 05 '13 at 11:39
  • I'm only using it for one variable (APP_NAME.users). I need to be able to modify the users variable across all my functions which are located in different modules/files. So its the only solution I could come up with. I didn't name it users because I want to avoid collisions. – C1D Sep 05 '13 at 11:42
  • 1
    It is a bad pracrice, if you keep on adding variables, if you make a habit of it. Using few variables doesn't mean it is bad. – user568109 Sep 05 '13 at 11:42
  • Also globals aren't really needed if you module.exports = {}; all modules requiring that will get the same object. – Pickels Sep 05 '13 at 11:43
  • @Pickels I understand that but they all need to be able to modify the variable and it have the same value across files. – C1D Sep 05 '13 at 11:44
  • @C1D It would be smarter to pass that APP_NAME.users variable as a parameter to your external files. Or to read it, export a function that calculates the "current" value of it. – Zlatko Sep 05 '13 at 11:55
  • @C1D the properties of that object will have the same value. If you redefine the object then you'll of course lose the reference. So if you required a module named foo and do foo = {} you set a new reference in the module requiring it and lose the reference to the original object. – Pickels Sep 05 '13 at 11:59

2 Answers2

16

Global variables are considered an anti-pattern in almost any programming language because they make it very hard to follow and debug code.

  • When you browse the code, you never know which function sets or uses a global variable. When all variables are either local or passed to a function, you can be sure that the side-effects of the function are limited.
  • Global variables work at a distance. Screwing with the value of a global could have unexpected effects in a completely different part of the application. When you debug an error caused by that, you will have a very hard time finding out where the variable was changed to a wrong value.
  • Global variables share a namespace, so you can inadvertently reuse them although you don't intend to do so.
  • It's hard to tell how important a global variable is. You never know if it's used by just two functions or if its value is important all over the place.
  • ...and many more reasons...

When you have two modules which share data, you should create an object with that data and explicitly pass it to each function which needs it (and only those which actually do).

Philipp
  • 67,764
  • 9
  • 118
  • 153
  • +1 Thank you so much. You found a better way for what I was trying to do. I switched to an object and now it works and is faster than global. – C1D Sep 05 '13 at 11:57
1

You can read from most of the comments and the other answers why is having a global considered bad practice. However, node.js apps are usually ran from a central point, like "app.js", "server.js" or something similar.

In that case, you can keep some sort of "config" (you said you need APP_NAME.users) as a config option to that file. So in "app.js" you have:

var config = {
  myVar: 100
}

If you need to access this variable in some of the modules, pass it as a parameter. Ie. in global file call it as:

var module = require('./lib/myModule.js').init(config);

Now your module can have it's init function exported, so that it sets its own local copy of config. Example:

var localConfig = null;
exports.init = function(config) {
  // merge the two config objects here
  localConfig.myVar = config.myVar;
}

Finally, you can have your local code affect the global object with it's private value. Something like this in your module:

exports.modifyGlobalConfig = function() {
  global.myVar = myLocalValue;
}

Your global app.js would then use that method to modify it's global value.

Zlatko
  • 18,936
  • 14
  • 70
  • 123