Using the Immediately Invoked Function Expression

Immediately-Invoked Function Expression (IIFE)

The Immediately Invoked Function Expression (pronounced iify) is an excellent way to write modular namespaces in javascript.  This pattern is sometimes also know as  a Self Executing Anonymous Function, but that is not the terminology I will use here because it is slightly misleading since the function does not actually execute itself.

No matter what the documentation says, the source code is the ultimate truth, the best and most definitive and up-to-date documentation you’re likely to find.

-Jeff Atwood @CodingHorror

It’s very common for a new javascript developer  to throw every bit of javascript code they write into a few very large Javascript files (2000+ lines of code). It’s not uncommon for a single Javascript file to be 2000+ lines of code. I cry a little inside every time I have to open a javascript file like this. It’s painful to read and navigate, and personally I like my code to be self-navigating. I believe a semi-competent programmer should be able to follow my code without explanation.

Your code is a story, make sure it’s a story worth reading.

Global variables in Javascript are Evil.

If you didn’t know adding lots of variables to the global namespace is a very bad practice, now you know. Adding variables to the global namespace has the following negative effects:

      • You are polluting the global namespace with your code.
      • You are not utilizing basic programming concepts such as public/private functions.
      • It is possible that another developer will overwrite your variables/functions, creating bugs in  your code that are out of your control.
      • Your code will be very hard to read and understand as your codebase gets larger.

Introducing the Immediately-Invoked Function Expression (IIFE)

Pros

  • Gives you the ability to have public and private properties and methods
  • Allows your library to grow across files using the “window.namespace = window.namespace || {}” technique
  • A common pattern that you will see in many libraries, widgets, and plugins

Cons

  • Slightly more complicated pattern that might makes new javascript developers a little uncomfortable, because unless it doesn’t require the use of the new keyword.

There is a great pattern that addresses all of these problems . All it takes are some simple changes to how we structure our code.  Here is a code sample demonstrating  IIFE pattern to create a namespace called myNamespace. We’ll name this file MyNamespace.js

Let’s look at the example and then I’ll explain the code afterwards.

(function (myNamespace) {

} (myNamespace = window.myNamespace || {}));

The first time I saw this pattern I was very confused about what I was looking at, but we’ll start at the outside and work into the tougher concepts.

The opening parentheses cause Javascript to evaluate the code inside as a function expression.  Inside the opening parentheses we have an anonymous function that takes one parameter, our namespace object. The function is empty for now, but you’ll notice that immediately after the closing curly bracket  there is another set of parentheses with a variable be created and passed as a parameter to the function we just defined.

These parentheses are invoking the anonymous function immediately after the declaration. Inside the method invocation we check to see if the namespace already has been created in another file by checking the window object for our namespace myNamespace. If window.myNamespace is undefined, then an empty object is assigned to the myNamespace parameter that we are passing around. By doing this we can make sure that if the namespace exists then we only extend it, and if it has not been created then we create an empty namespace object.

Ok So Now What ?

We have a namespace.  Lets see how we can extend it :

(function (myNamespace) {

    //Private Variable
    var helloWorldMessage = "Hello Javascript";

    //Private Function
    var sayHi = function () {

        console.log(helloWorldMessage);

    };

    //Public Function
    myNamespace.helloWorld = function () {

        //call our private method
        //Prints "Hello Javascript" to the console
        sayHi();
    };

} (myNamespace = window.myNamespace || {}));

The IIFE pattern makes hiding functionality that shouldn’t change with private variable/functions easy, and exposes a nice public API for any consumer of this code. Now lets create another javascript file that extends this namespace to add some different functionality. Let’s call this file MyNamespaceExtension.js

(function (myNamespace) {

    //Private Variable
    var goodbyeMessage = "Goodbye Javascript";

    myNamespace.goodbyeJavascript = function () {

        console.log(goodbyeMessage);

    };

} (myNamespace = window.myNamespace || {}));

How Do I Use It ?

To use the namespaces we just defined we simply need a reference to the files and then we can instantly call them after they are loaded.

<html>

<head>

    <script src="../Scripts/MyNamespace.js" type="text/javascript"></script>

    <script src="../Scripts/MyNamespaceExtension.js" type="text/javascript"></script>

<script>

    myNamespace.helloWorld();

    myNamespace.goodbyeJavascript();

</script>

</head>

</html>

But I Need Nested Namespaces !

If you want to create a more complex namespace you can use the same creation pattern to create a new namespace within one of our modules.

(function (myNamespace) {

    //create a nested namespace
    myNamespace.nestedNamespace = myNamespace.nestedNamespace || {};

    //add a public function to our new namespace
    myNamespace.nestedNamespace.nestedMessage = function () {

        console.log("A clever message");
    };

} (myNamespace = window.myNamespace || {}));

And to call use the new namespace:

<html>

<head>

    <script src="../Scripts/MyNamespace.js" type="text/javascript"></script>

    <script src="../Scripts/MyNamespaceExtension.js" type="text/javascript"></script>

    <script src="../Scripts/MyNamespace.NestedNamespace.js" type="text/javascript"> </script>

<script>

    myNamespace.helloWorld();

    myNamespace.goodbyeJavascript();

    myNamespace.nestedNamespace.nestedMessage();

</script>

</head>

</html>

Summary:

      • We have severely reduced the footprint on the global namespace.
      • We have encapsulated functionality with a reliable pattern, exposing only a small subset of our code.
      • It is much less likely that your code will get stomped out by another developer.
      • It is now very easy to split our codebase up into separate files
About these ads

One thought on “Using the Immediately Invoked Function Expression

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s