One of the often used coding patterns with functions has got a fancy name for itself: Immediately-invoked Function Expression. Or more dearly known as IIFE and pronounced as “iffy.”
The natural function definition
- Lines 1–3 define a function named sayHi.
- On line 5 we call it with the usual “()” syntax to invoke the function.
These function definitions always start with the function keyword and are always followed by a name for the function. You can’t omit the name as it’s invalid syntax.
- Line 1 declares msg variable and assigns a string value to it.
- Lines 2–4 declare sayHi variable and assign a value to it that’s of function type.
- Line 6 calls this sayHi function.
Line 1 is trivial to understand. But when developers see lines 2–4 for the first time, it usually defies their expectations if they are coming from other programming languages like Java.
Basically, in lines 2–4 we assigned a value that’s of function type to a variable named sayHi.
Anonymous function expressions
Well, you already know what they are. The above example was an anonymous function expression. They are anonymous because they don’t have a name following the function keyword.
Named function expressions
Function expressions can have names. The most boring and universally explained usage of these named function expressions is with recursion. Don’t worry much about these now as you can master IIFE without understanding named function expressions.
So the difference here is that the function expression has a name “fibonacci” that can be used inside that function expression to call itself recursively. (There is more to it like the function name shows up in stack-traces and etc, but let’s not worry about them in this tutorial.)
Enough! Show me an IIFE or I am leaving now!
Now that you have learned function definitions and function expressions, let’s dive right into the secret world of IIFEs. They come in a few stylistic variations. Let’s first see a variation that’s really, really easy to understand.
That’s my friends, is our dear IIFE in action! When you copy this code and try in a browser’s console, you will see the alert from code on line 2. And that’s pretty much it. No one can ever get this alert to show up again.
That’s a function that died immediately after it came to life.
Now let’s understand that not so intuitive syntax: I know you spotted that “!” on line 1; If you did not, no worries, you would have spotted it now!
- But the most interesting stuff happens on line 3 where we execute that function expression immediately.
So we have a function expression that’s immediately invoked after it’s created. And that’s, my friends, is called an IIFE irrespective of the stylistic variation used to achieve this effect.
The above stylistic variation can be used by replacing “!” with “+”, “-”, or even “~” as well. Basically any unary operator can be used.
Now, give it a try in the console! And play around with the IIFE to your joy!
All that the first character, “!”, is doing here is to make that function into an expression instead of a function statement/definition. And then we execute that function immediately.
Another quick variation on this is shown below:
Again void is basically forcing the function to be treated as an expression.
All the above patterns are useful when we are not interested in the return value from the IIFE.
But then what if you wanted a return value from the IIFE and you want to use that return value elsewhere? Read on to know the answer!
Classical IIFE style
The IIFE pattern we have seen above is easy to understand. So I started with that style first instead of the other more traditional and widely used style.
As we saw in the above IIFE examples, the key to IIFE pattern is taking a function and turning it into an expression and executing it immediately.
First, let’s see yet another way to make a function expression then!
In the above code, a function expression is wrapped in parentheses in lines 1–3. It’s not yet an IIFE as that function expression is never ever executed. Now to convert that code into an IIFE, we have following two stylistic variations:
Now we have got two IIFEs in action. It might be really tough to notice the difference between Variation 1 and Variation 2. So let me explain that.
- In Variation 1, on line 4, parentheses () for invoking the function expression is contained inside the outer parentheses. Again outer parentheses are needed to make a function expression out of that function.
- In Variation 2, on line 9, parentheses () for invoking the function expression is outside the wrapping parentheses for the function expression.
Both variations are used widely. I personally prefer Variation 1. If we get into the nitty-gritty, both variations differ slightly on how they work. But for all practical purposes and keeping this already long tutorial short, I am going to say you can use either one of them to your liking. (I will link to a future article that I plan to write on () operator and comma operator that clarifies nuances between these two styles.)
Let’s nail this down through the wall again by seeing an example that works, and two examples that don’t work. We will start naming our IIFEs from now as using anonymous functions is usually never a good idea.
Now you know why that weird looking surrounding parentheses around the function expression are needed to form an IIFE pattern.
Remember this! You need a function expression to form an IIFE. Function statements/definitions are never used for creating IIFEs.
IIFEs and private variables
One thing that IIFEs are really good at is to do with their ability to create a function scope for the IIFE.
Any variables declared inside the IIFE are not visible to the outside world.
Let’s see an example.
In this example, we have declared two variables inside the IIFE and they are private to that IIFE. No one outside the IIFE has access to them. Similarly, we have an init function that no one has access to outside the IIFE. But the init function can access those private variables.
When we see module pattern, I will explain how to give privileged and controlled access to these private variables to the world outside the IIFE. So read on to know that even if you already feel like an IIFE Ninja!
IIFEs with a return value
If you don’t need a return value from an IIFE, then you could always use the first stylistic IIFE variation that we saw with unary operators like !, +, void, and etc.
But another really important and powerful feature of IIFEs is that they can return a value that can be assigned to a variable.
- In this variation, we have an IIFE that has a return statement on line 2.
- When we execute the above code, line 5 shows the alert with the return value from the IIFE.
Basically, the IIFE is executed, immediately of course, and then the return value from it is assigned to the result variable.
This is a really powerful pattern that we are going to use as we look at the example of module pattern.
IIFEs with parameters
Not only IIFEs can return values, but IIFEs can also take arguments while they are invoked. Let’s see a quick example.
- In the above example, on line 1, IIFE has two formal parameters named msg, times respectively.
- When we execute the IIFE on line 5, instead of the empty parentheses () we have seen so far, we are now passing arguments to the IIFE.
- Lines 2 and 3 use those parameters inside the IIFE.
This is a really powerful pattern and we see this often in jQuery code and in other libraries as well.
In the above example, we are passing jQuery, window, and document as arguments to the IIFE on line 3. The code inside the IIFE can refer to them as $, global, document respectively.
Here are a few advantages of passing these to the IIFE.
Now that you have mastered IIFEs, let’s see an example of module pattern that puts IIFEs and closures on steroids.
We will implement a classic Sequence singleton object that works seamlessly without anyone being able to accidentally corrupt the current sequence value.
We will write this code in two steps so we understand what’s happening incrementally.
- In the above example, we have an IIFE that returns an object. See line 7 and 8.
- We also have a local variable in the IIFE named current.
- The return value of the IIFE, which is an object in this example is assigned to the Sequence variable. Line 12 properly alerts “object” since we are returning an object from the IIFE.
Now let’s improve this by adding a few functions on the object that we return.
- In this example, we add two functions on the object that we return from the IIFE.
- Lines 8–10 add getCurrentValue function that returns the value in current variable
- Lines 12–15 add getNextValue function that increments the value in current by 1 and then returns the value in current.
Since current variable is private to the IIFE, no one but the functions that have access to it through closure can modify or access the current variable.
This is a very basic variation on the module pattern. There are more patterns, but almost all of them use an IIFE to create a private closure scope.
When you can omit parentheses
Parentheses around the function expression basically force the function to become an expression instead of a statement.
But I always prefer to use the parentheses even in this case. Using parentheses improves readability by stylistically hinting the reader on the first line that the function is going to be an IIFE. They don’t have to scroll to the last line of the function to realize what they just read through was an IIFE after all!
That’s all there is to know about IIFEs to start using them in your code. They not only help organize and express your code more beautifully, they also help you in reducing bugs by avoiding creation of unnecessary globals. Now, you are a Certified IIFE Ninja!
If you have any thoughts and ideas about this tutorial, you can always leave a response below. If you want me to write about any other topics, please leave a message as well.