Javascript IIFEs

Oct 29, 2017 20:03 · 695 words · 4 minutes read programming

Therein lies the paradox of Javascript, the Achilles’ Heel of the language, the challenge we are presently addressing. Because JavaScript can be used without understanding, the understanding of the language is never attained.

Kyle Simpson
You Don’t Know Js: Up & Going


IIFEs is a term that is used in the JavaScript world alot. The term IIFE is an acronym for: Immediately Invoked Function Expression. Many people have encountered IIFEs in external JS libraries yet they have blindly ignored how they work. I’ve sadly been a culprit of this in the distant past. I reminisce copy-pasting some chunk of code from a stack-overflow thread which worked well without bothering how IIFEs in that code affected the codebase- I was content with things working just fine. This article is my attempt to demystify what IIFEs are in addition to outlining where and how to use them.

First, IIFEs have this general form:


\\ Here's the general form:
(function()
{
    \\ Some code goes here
})();

\\ Here's an example:
(function( x ){ console.log( x + 1); })(x);

\\ Running this results in:
\\ 4

When the interpreter runs into an IIFE, it immediately invokes it. To gain a better understanding of how IIFEs work, you first have to differentiate between function expressions and function declaration(also called function statements). The difference between these two is best explained by examples.

This is an example of a function declaration:

function test() {
    console.log('a test');
}

This is a function expression:

var test = function() {
    console.log('a test');
}

1The main difference between a function declaration and a function expression is the function name, which can be omitted in function expressions to create anonymous functions.

Now back to IIFEs. Note that IIFEs have this general form:

(<some function expression goes here>)(args...)

A more concise way of writing this would be:

((<some function expression goes here>)(args...))

The latter is more concise because of the extra pair of parens which make the function more readable. A function without a name(a function expression) is created and then called(invoked) immediately via the parens, (), at the very end hence the name: Immediately Invoked Function Expression.


Scoping

A common use of IIFEs is to control scoping. Below is a common example that illustrates this:

Let’s assume you want to maintain the count of something useful in your codebase. One simple way to do this would be to define some variable say i, with which you would use to track the count.

var i = 0;

\\ Let's assume we have a link and we want to track how many times
\\ this link is clicked

var testing = document.getElementById('test');
testing.addEventListener('click', function(e){
    e.preventDefault();
    ++i;
    alert( 'Counter: ' + i);
}, 'false');

Notice how the variable i ‘pollutes’ the global namespace. Perhaps in another part of you codebase, you’d accidentally use i for something else and this would make your tracker inaccurate. A simple way to circumvent this is to use IIFEs. Here’s an example:

// Defining the counter IIFE
var counter = ((function () {
    var i = 0;
    return {
        reset: function() {
    		i = 0;
    	},
        get: function() {
    		return i;
    	},
        increment: function() {
      	    ++i;
        }
    }
})());

// Adding an event listener
var el = document.getElementById('track');
el.addEventListener('click', function(e){
  e.preventDefault();
  counter.increment();
  console.log( 'Counter: ' + counter.get());
  if (counter.get() > 3) counter.reset();
}, 'false');


In the above example, we keep track of the count using the same variable, i, whose state using closures in an IIFE. The variable i is not in the global scope but instead lives in an internal scope within the IIFE. Also, notice, how you can add any other functionality easily(like reset) to the counter variable.

Common Gotchas

A common error when using an IIFE is omitting the enclosing brackets that wrap around a function. Here’s an example:

\\ This will throw an error
function() {console.log('test')}();

\\ This is correct
(function(){console.log('test')})();

Summary

In this article, I’ve looked at what IIFEs are and how they work by examining the difference between function expressions and function declarations. I’ve also discussed scoping and some common pitfalls when using IIFEs. I hope this article has proved to be useful.

References:
[1] Function Expression