Reputation: 21314
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
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