2

I've been writing web applications for a while now , and everyone knows the one golden rule not to assign variables to the window object , don't ever assign a variable without using var.

My question is, why not? In my opinion it is a lot easier especially nice in SPA's to attach objects to the global scope when you have many different scopes in different modules for different modal views if you want to share data.

Now, lets just assume for the sake of this question that I will never ever have the problem of accidentally overriding global variables, meaning - I will take the responsibility to make sure I have very good names and they will never overlap. If you take that into consideration , then I can't see any other reason why global variables are just bad practice.

2

5 Answers 5

6

For a few reasons:

  • It often forces you to choose longer names, where a shorter one would be more clear and concise within a limited scope. For example, filter versus MyModuleNameFilter.
  • The process of "taking the responsibility to make sure you have very good names and they will never overlap" gets increasingly difficult the larger your code base gets (and the older you get for that matter).
  • You are unable to share code with anyone else who subscribes to the same philosophy.
0
8

Because global variables have global scope, they are visible, and mutable, by anything that runs on the page. That introduces implicit coupling between all code running on the page; everything could interact with everything.

That runs contrary to the concept of encapsulation. If your code and variables are local in scope, it's easier to reason about things; only those parts of the code that can access the variable may have changed it.

When it comes to variables attached to the window object, you never know where they have been, or who has touched them.

0
2

"I will take the responsibility to make sure...".

Many unexpected babies arrive that way.

But seriously:

  • keeping names unique with a growing code base that may include other libraries is a difficult and risky process that is ultimately doomed to failure.
  • your very own code will start to get really hard to read and follow when you set and read these variables in different places. When it comes to a given section of code, you may not be sure of the value of the variable and that can be a problem.
  • variable naming should be based on a good name for the method, not on what names you have already
  • common names should be repeatable. It should be ok to have names such as 'filter','create','new','index','search', etc. in multiple places. Without namespacing of some kind you can only have these functions once.
0
2

"Never put variables in global scope" is a best practice because it makes those variables brittle. A typical web page or especially a typical web application is likely to contain many different scripts from multiple sources, and as careful as you may be to track your own global variables, everyone else whose scripts you're referencing may not be playing along.

Think of it like vaccines. If everyone had a vaccine, there'd be no threat, and if you alone have a vaccine there's no threat, but meanwhile everyone else is trying to get vaccinated, so you could probably get away with not being vaccinated because no one else is your threat, but that's just not playing nicely with the scripting ecosystem you're working in.

There is some latitude with using globals if you namespace. The root of your namespace is a global, but you're allowed only the one namespace root variable. That's a compromise that the Javascript community is usually okay with, particularly if it is limited to your application.

A namespace might look like this:

window.MyNamespace = {
    ClassA: function() { },
    NestedNamespace1: {
        ClassB: function() { }
    }
};

This puts ClassA and ClassB in the nesting of the MyNamespace namespace:

(function() {
    var myClassAInstance = new MyNamespace.ClassA();
    var myClassBInstance = new MyNamesapce.NestedNamespace1.ClassB();
})();

You can also build it up using namespacing functions like the one I created [here], which also explains further how you can take advantage of the simplicity of namespacing.

Generally, however, the recommendation is to use closure variables everywhere. Namespaces are a minimum, but discouraged because of the benefits of closure variables. A closure variable is a variable declared within the execution of a function. All script files that you write should be contained within a function.

(function() { // IIFE (immediately-invoked function expression)

   var myClosureVariable = 3;
   $('#myDomElement').on('click', function() {
       console.log(myClosureVariable); // outputs 3
   });

})();
console.log(myClosureVariable); // outputs undefined
1
  • aw .. I sad dat I not your accepted ansur .. :P you're welcome
    – stimpy77
    Mar 25, 2015 at 16:08
-1

Let us consider some different use cases:

  1. You have a variable that is only relevant for the duration of a function call, or within a specific closure. While using a global may not turn out to become a problem, it doesn't give you any benefit either. Making it local is the safe and easy choice.

  2. You are writing a library, your code will be used in conjunction with code that you have no control of. The global scope is not yours to mess with. The only legitimate reason for using the global scope is in order to expose public library functions. These cases must of course be documented so that the library user can avoid name collisions.

  3. You are writing your own project and you have a variable with a lifespan beyond your functions. You could do any number of things to avoid making it a global, but that tend to simply make your code more complicated, with no real advantage to show for it. Just make it global, it is the simple solution to a simple problem. Declaring it explicitly in your globals declaration section will document its existence.

  4. You are part of a team, and you have a reasonable need for a global. This falls somewhere between case 2 and 3. If the variable need only be global to your module, then making a closure for it may be the best tradeoff. If it transcends what is possible with your own closure, a global may still be the best choice. Remember to document it in whatever fashion is customary for the project.

Globals are just fine when used in a prudent manner. The tricky part of the debate is that you can't ignore the broader context in which the code is written.

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