Using IIFEs in JavaScript to control variable scope

March 25, 2015 Josh Mock

On a recent project, a few of us have been challenged to take our JavaScript skills to a new level. We’ve even learned a few new tricks from a group of outside developers that we’re working with who specialize in JavaScript.

One such trick is using immediately-invoked function expressions (IIFEs), which are often used to take advantage of JavaScript’s scope rules to funnel in certain global variables and avoid creating too many of your own globals.

The basic concept of an IIFE (lovingly pronounced “iffy,” occasionally referred to as a self-executing or self-invoked anonymous function) is to wrap a portion of JavaScript in an anonymous function that gets called immediately:

(function () {
     // your code here
})();

Wrapping the function in parentheses turns it into an expression rather than a declaration. The empty set of parentheses that follows tells the interpreter to run that expression as a function. It is a more compact and anonymous equivalent to the following:

var foo = (function () {
     // your code here
});
foo();

Take control of your globals

Writing code like this might seem redundant until you give it more substance, of course. Let’s use an example I recently came across in a website I was working on at home.

This website, unfortunately, has dependencies on both the jQuery and Prototype libraries. Both libraries use $ as a global variable; Prototype as a shortened way to access document.getElementById(), and jQuery for, well, pretty much everything it does. Because of this, the value of $ changes depending on which library is included last. In this case, Prototype was the last-included library, so $ belongs to Prototype.

Now if I want to use jQuery’s functions, instead of using $( ... ), I have to use jQuery( ... ). This is a little annoying, what with jQuery being the more widely-used library that more developers are familiar with. To fix this, I wrapped my code in an IIFE and passed it the jQuery global variable:

(function ($) {
     $(document).ready(function () {
          // my code
      });
})(jQuery);

This means that, no matter what the global variable $ means outside my IIFE, within it I’m explicitly telling it to run jQuery functions. I could just as easily assign jQuery to any other unused variable and it would have the same effect:

(function (p) {
     p(document).ready(function () {
          // my code
     });
})(jQuery);

Keep your variables to yourself

Aside from funneling in global variables to whatever values I want, I can also use IIFEs to prevent variables from being added to the global scope.

For example, you might run the following code on a web page outside of any function:

var x = "hello";
alert(x); // alert dialog with the text "hello"

By doing this, x is now a global variable. If x was assigned elsewhere before this script was called, it’s now reassigned to the value "hello". Not always ideal. To avoid this without having to name and call a new function, wrap your code in an IIFE. This keeps your variables within a smaller scope and still runs the lines immediately:

(function() {
     var x = "hello";
     alert(x); // alert dialog with the text "hello"
})();

Now, x is only assigned to the value "hello" for the duration of the IIFE. If x was assigned globally before the IIFE, it would keep that value after the IIFE runs:

var x = "foo";
(function() {
     var x = "hello";
     alert(x); // alert dialog with the text "hello"
})();
alert(x); // alert dialog with the text "foo"

As you’ve seen, the IIFE convention can be a great standard practice when writing your own libraries and plugins, when extending JavaScript where you may not be aware of every context in which certain variable names are used and to prevent too much data from creeping its way into the global scope.

Previous Article
A new platform for Emma

We’ve been sharing details about our API for a while now here on Emma Tech, and we’re excited to announce t...

Next Article
Making a match: Salesforce and Emma

Salesforce is clearly a juggernaut. Businesses from the smallest retail bakery to Fortune 500 behemoths are...