10

I have a very simple question that has been haunting me for a while when my code starts growing.

Should parameters be replaced by global variables when they go through long routes of nested function calls?

I understand that global environment can make the state of a program unpredictable because many functions can modify shared variables, but still, global space makes things so easy.

Let me explain myself:

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.
}

Replaced by:

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

I feel the second way gives so much freedom to program because parameters can accumulate easily and also can be very restricting sometimes when code must be reused, but at the same time I feel like the function will loose its modularity when it is related to a variable in the global environment, also loosing reusability when, for example, I want to operate finallyDoSomethingWithX with another variable different tha globalX.

I think this is happening to me because I'm not actually using design patterns because I'm programming in Javascript, which for me feels like a one-script-deals-with-all language for medium projects.

Any advices? patterns? I can be more specific if needed.

  • 5
    Typically, if you're passing variables very deeply, you haven't broken the problem up correctly. As for global variables driving state elsewhere in the system, avoid it like the plague. It's impossible to manage at a certain point, and you will find things breaking randomly because some state is mutated by a function that you weren't expecting randomly. – mgw854 Apr 14 '17 at 21:25
  • Avoid it like the plague. Understood. Could you elaborate a little more on "you haven't broken the problem up correctly". I understand the general idea but I can't come up with an example or something to reeeally understand it. – AFP_555 Apr 14 '17 at 21:32
  • 2
    A common remedy when you find yourself passing arguments many layers deep is to create a method object: an object of a new class whose methods correspond to the functions that pass the parameters along. The parameters can then become variables local to the object, and its methods need not pass along the values anymore. – Kilian Foth Apr 14 '17 at 22:20
  • @KilianFoth Thanks. Could you please elaborate with some code so I can check the answer? – AFP_555 Apr 14 '17 at 22:26
  • 1
    Consider treating the structure of your JavaScript code as you would in other languages (such as those which use "real" classes). Some useful links on this related question on SO: stackoverflow.com/questions/927651/… – Ben Cottrell Apr 15 '17 at 0:31
7

Don't use global variables.

Also, don't pass parameters down chains of functions!

Its difficult because you don't use an actual example. But normally there will be a better approach.

Lets say we have a password variable which we need to use to call apis which inturn are used by various low level functions.

Global approach (psudo code)

var pass;

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

Parameter passing approach

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

Object approach

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

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}
  • Excelent. This way pass is not in the global environment and also is not a parameter for múltiple functions as it can be taken from the object's attributes. Thanks. – AFP_555 Apr 15 '17 at 14:14
3

Avoid globals like the plague.

Any code can modify a global. So if you had a chain A(x) -> B(x) -> C(x) -> ... -> Z(x), and you store x into a global X and now you have a chain A->B->C->...->Z, then at every single step of that long chain, or in completely independent code, someone could change X. And the value that Z uses could be completely different from the one that A started with.

It's a nightmare if you ever want to be sure that your code does what it it is supposed to do, or that it does what you think it does.

  • Totally agree. If you use globals to solve your problem, now you have two problems. – Caleb Mauer Jul 13 '17 at 18:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.