Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is meant by “leaking” into global scope?

A while ago, I offered-up a JavaScript design pattern (the Module Pattern - see below) that I got from a John Resig example as part of a solution to someone’s question and I received the following comment:

“…that pattern is a bit over engineered and not that good. Still leaking into global-scope. and your not opening yourself to async loaders. But it is better then just ad-hoc coding !”

So…

If “leaking” into global scope means “your object gets appended to the browsers window (object)”…then everything already gets appended (globally):

This “leaks” into global scope:

window.jQuery

…just call: window.jQuery and it resolves as a function();

This “leaks” into global scope:

function HelloWorld() { alert(‘Howdy’); }

…just call: window.HelloWorld() and you will get ‘Howdy’.

This “leaks” into global scope:

var myVariable = 10;

…just call: window.myVariable and you will get 10

If the commenter is correct, then all the above “leak” into global-scope. So, personally, I don’t see a way NOT to “leak” into global-scope as even your form controls exists there (as well).

As such, here are my questions…

  • What is meant by “leaking” into global-scope?
  • Why is that bad?
  • How do you avoid it?
  • When wanting to create persistent custom-objects, why is the Module Pattern (below) bad?
  • Design patterns let you encapsulate complex logic, is encapsulation suddenly bad simply because we’re writing in JavaScript?
  • Or...is this commenter simply wrong?

Here is the Module Pattern I Mentioned Above:

<script type="text/javascript">
    var myNamespace = (function($) {
        var publicInstances = {};

        // ***********************
        // myObject
        publicInstances.myObject = myObject;
        function myObject() {

            /// <summary>A pointer to this</summary>
            var self = this;

            this.someProperty = new String();

            this.initialize = function() {
                /// your code here
            }
            this.someMethod = function() {
                /// your code here
            }

            self.initialize();
        }

        return publicInstances;
    })(jQuery);


    jQuery(document).ready(function() {
        // Use would look like
        var myInstance = new myNamespace.myObject();
    });
</script>


UPDATED:
I’m satisfied with the answers below and want to thank everyone for taking the time to comment.

TO RECAP THE ANSWERS BELOW:
"Leaking" into global-scope occurs when something used in local-scope is unintentionally made available to the global-scope (e.g. the window object). This is bad because it opens the page to potential naming collisions which could result in variables resolving to unexpected values or types.

Intentionally making a variable global is not considered a "leak". However, properly namespacing the object is required to reduce potential for said naming collisions.

You cannot avoid globally-scoped variables, but you can reduce the above risks by using asynchronous-loaders and defining-modules made available in plug-ins like RequireJS or Curl.

like image 207
Prisoner ZERO Avatar asked May 10 '11 14:05

Prisoner ZERO


1 Answers

"Leaking" into global scope is when something used in a local scope is unintentionally made available to the global scope. That means assigning to a variable not already defined in the current scope:

function myFunction() {
    a=1;
}

myFunction();
alert(a);
//-> 1

It's bad because there could be naming collisions resulting in variables with different values/types than expected. It can also lead to a bug in older Internet Explorers when you forget to use the var keyword for a variable used in a for statement.

I wouldn't class intentionally making a variable global as "leaking", because it's more like you're "pouring" it into the global scope. However, this is still often considered bad practice by some (although I think that's a little melodramatic) because there are still potential naming collisions with current properties of the window object, or variables set by other scripts and libraries.

like image 135
Andy E Avatar answered Oct 11 '22 07:10

Andy E