views:

154

answers:

5

I have been reading a lot of Javascript lately and I have been noticing that the whole file is wrapped like the following in the .js files to be imported.

(function() { ... code ... })()

What is the reason for doing this rather than a simple set of constructor functions?

+4  A: 

That's called a closure. It basically seals the code inside the function so that other libraries don't interfere with it. It's similar to creating a namespace in compiled languages.

Example. Suppose I write:

(function() {

    var x = 2;

    // do stuff with x

})();

Now other libraries cannot access the variable x I created to use in my library.

Joel Potter
Careful with your terminology. Namespacing implies that the variables can be accessed from outside by addressing the namespace (typically by using a prefix). While this is possible in Javascript that isn't what's demonstrated here
Gareth
I agree it is not exactly like a namespace, however, you can provide similar functionality by returning an object with properties which you want to publicize: `(function(){ ... return { publicProp1: 'blah' }; })();`. Obviously not perfectly parallel to namespacing, but it may help to think of it that way.
Joel Potter
+5  A: 

Javascript in a browser only really has a couple of effective scopes: function scope and global scope.

If a variable isn't in function scope, it's in global scope. And global variables are generally bad, so this is a construct to keep a library's variables to itself.

Gareth
But doesn't the constructor function itself provides scope for its own variables?
Andrew Kou
Yes, each function defined in this library could define its own local variables, but this allows variables to be shared between the functions without them leaking outside of the library
Gareth
+11  A: 

It's usually to namespace (see later) and control the visibility of member functions and/or variables. Think of it like an object definition. jQuery plugins are usually written like this.

In Javascript, you can nest functions. So, the following is legal:

function outerFunction() {
   function innerFunction() {
      // code
   }
}

Now you can call outerFunction(), but the visiblity of innerFunction() is limited to the scope of outerFunction(), meaning it is private to outerFunction(). It basically follows the same principle as variables in Javascript:

var globalVariable;

function someFunction() {
   var localVariable;
}

Correspondingly:

function globalFunction() {

   var localFunction1 = function() {
       //I'm anonymous! But localFunction1 is a reference to me!
   };

   function localFunction2() {
      //I'm named!
   }
}

In the above scenario, you can call globalFunction() from anywhere, but you cannot call localFunction1 or localFunction2.

What you're doing when you write (function() { ... code ... })(), is you're making the code inside a function literal (meaning the whole "object" is actually a function). After that, you're self-invoking the function (the final ()). So the major advantage of this as I mentioned before, is that you can have private methods/functions and properties:

(function() {
   var private_var;

   function private_function() {
     //code
   }
})()

The neat thing is that you can also define things inside and expose it to the outside world so (an example of namespacing so you can basically create your own library/plugin):

var myPlugin = (function() {
 var private_var;

 function private_function() {
 }

 return {
    public_function1: function() {
    },
    public_function2: function() {
    }
 }
})()

Now you can call myPlugin.public_function1(), but you cannot access private_function()! So pretty similar to a class definition. To understand this better, I recommend the following links for some further reading:

EDIT

I forgot to mention. In that final (), you can pass anything you want inside. For example, when you create jQuery plugins, you pass in jQuery or $ like so: (function(jQ) { ... code ... })(jQuery). So what you're doing here is defining a function that takes in one parameter (called jQ, a local variable, and known only to that function). Then you're self-invoking the function and passing in a parameter (also called jQuery, but this one is from the outside world and a reference to the actual jQuery itself). This is because everything you define inside is effectively inside the function. So if you need to know about anything from the outside world, you need to pass it in.

Vivin Paliath
Very cool, I understand namespace well, but I've seen a lot of that last example of yours and couldn't figure out what people were trying to achieve. This really clears things up.
Andrew Kou
+4  A: 

In addition to keeping the variables local, one very handy use is when writing a library using a global variable, you can give it a shorter variable name to use within the library. It's often used in writing jQuery plugins, since jQuery allows you to disable the $ variable pointing to jQuery, using jQuery.noConflict(). In case it is disabled, your code can still use $ and not break if you just do:

(function($) { ...code...})(jQuery);
Coronus
A: 

You can use function closures as data in larger expressions as well, as in this method of determining browser support for some of the html5 objects.

   navigator.html5={
     canvas: (function(){
      var dc= document.createElement('canvas');
      if(!dc.getContext) return 0;
      var c= dc.getContext('2d');
      return typeof c.fillText== 'function'? 2: 1;
     })(),
     localStorage: (function(){
      return !!window.localStorage;
     })(),
     webworkers: (function(){
      return !!window.Worker;
     })(),
     offline: (function(){
      return !!window.applicationCache;
     })()
    }
kennebec