atconway
atconway

Reputation: 21314

Why assign an IIFE to a variable?

I've been using IIFE in JavaScript and in AngularJS and have been using the following structure:

Method 1:

//IIFE Immediately Invoked Function Expression
(function () {


}());

However, I've seen the following often where a variable is assigned to the IIFE

Method 2:

//IIFE Immediately Invoked Function Expression assigned to doStuff variable
var doStuff = (function () {


}());

NOTE: This question is NOT about what this pattern is or what an IIFE is. This is pertaining specifically to why one would use a return variable on an IIFE and its relation to Angular practices as well.

In Angular Method 1 works fine, but in many of the raw JS examples I see, Method 2 is used. My assumption is that anything encasulated in doStuff will be avliable via it and callable. However, I'm not 100% sure on the exact reasoning or distinction between the 2 methods and need some help understanding when to use the different methods?

Upvotes: 15

Views: 6630

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074909

The reason for Method #2 is that you'll find code within the IIFE that returns something (typically, but not necessarily, an object or a function). What the IIFE returns is what ends up being assigned. E.g.:

//IIFE Immediately Invoked Function Expression assigned to doStuff variable
var doStuff = (function () {
    var privateInformationForDoStuff = 0;

    function doStuff() {
        console.log(++privateInformationForDoStuff);
    }

    return doStuff;
}());

There, the variable ends up being a reference to a function that, each time it's called, gives us a number higher than the previous time. The IIFE is there to ensure that nothing can modify the privateInformationForDoStuff variable, it's entirely private to the doStuff function.

It was common to use this (sometimes called the "revealing module pattern") to create objects with various functions on them which might also have private information that's only shared within the "module":

var MyApp = (function() {
    var privateModuleInformation;
    var morePrivateModuleInformation;
    // ...

    function doThis() {
        // ...
    }

    function doThat() {
        // ...
    }

    function doTheOther() {
        // ...
    }

    return {
        doThis: doThis,
        doThat: doThat,
        doTheOther: doTheOther
    };
})();

In modern environments you'd use an actual module instead, but that didn't used to be an option.

Upvotes: 17

Related Questions