"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