Immediate functions

These are self-invoking functions, i.e functions that initialize themselves.
The general syntax looks like this:

(function() {
// do stuff here
})();

In the above code, the function operator (), in line 3, applies to the whole anonymous function, which is also enclosed in a set of parenthesis (...). So the anonymous function is being used like an expression just like common mathematical expressions: (6 + 2)*5 and 6 + (2*5). The parenthesis contain an expression that must be resolved first before applying the * or + operators respectively.

This technique is extremely useful in advanced JavaScript and is employed in most JavaScript libraries ranging from jQuery to Prototype. A single expression performs three main tasks:

  1. It creates an instance of the anonymous function
  2. It invokes the anonymous function
  3. It removes all references to the anonymous function at the end of the statement

It’s important to note that the anonymous function creates a closure or self-contained scope.

Simulated access control

Immediate functions can be used to create OOP-like features in JavaScript. Self-contained scopes help to make modular constructs as well as private variables, possible. The snippet below illustrates an example.

(function() {
   var clickCount = 0;
   document.addEventListener("click", function(){
      alert(++clickCount);
   ), false);
})();

Since the anonymous or immediate function is invoked as soon as the script is launched, the click event handler is bound at the same time. This handler is within the same closure as the clickCount variable. As a result, clickCount acts like a private variable for the event handler. It can only be referenced within the self-contained scope of the anonymous function.

In the example above, the immediate function had no arguments or parameters. There are several very important practical applications for this technique. The most common is perhaps with the jQuery $ alias, which is also used by other libraries such as Prototype. When using two libraries that have the same alias, you can avoid name space conflicts by adding a parameter to the immediate function.

<body>
<input type="button" value="click" />
<script type="text/javascript">
  $ = function(){ alert ('$ is not jQuery!'); };
  (function($){
     $('input').on('click', function(e){
        $(e.target).addClass('btnclick');
      })

  })(jQuery);
</script>
</body>

run the code

Looping with immediate functions

Closures and loops require special attention in order to avoid common pitfalls. For example in the code below, the result is not what you might expect.

<body>
    <ul>
       <li>first item</li>
       <li>second item</li>
       <li>third item</li>
   </ul>
<script type="text/javascript">
    var items = document.getElementsByTagName("li");
    for(var i = 0; i < items.length; i++) {
      items[i].addEventListener("click", function() {
      alert("item # " + i + " was clicked");
      }, false);
    }
</script>
</body>

run the code
As you can see in the above code, the alert always points to the last item in the list. This happens because the closure references the enclosed variables and the last value over rides all previous values. There’s a simple solution to this problem using another immediate function but passing a parameter as the function’s argument as shown below:

<body>
    <ul>
       <li>first item</li>
       <li>second item</li>
       <li>third item</li>
   </ul>
<script type="text/javascript">
    var items = document.getElementsByTagName("li");
    for(var i = 0; i < items.length; i++) (function(count){
      items[i].addEventListener("click", function() {
      alert("item #" + count + " was clicked");
      }, false);
    })(count);
</script>
</body>

run the code

The body of the previous for loop has been replaced by the immediate function. Each time the loop runs the value of the counter is passed as the argument of the new immediate function, as result each loop has a different value. This value is then passed onto the alert, which is within the scope of the new immediate function.