Essential JavaScript: Mastering Immediately-invoked Function Expressions
Understanding functions inside out and then learning how to exploit them to write modern, clean JavaScript code is a critical skill for becoming a JavaScript ninja.
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.”
Before we can understand what an IIFE is and why we need one, we need to review a few fundamental concepts around JavaScript functions quickly.
The natural function definition
Developers new to JavaScript are naturally comfortable with the following syntax when dealing with functions.
- Lines 1–3 define a function named sayHi.
- On line 5 we call it with the usual “()” syntax to invoke the function.
This way of creating a function is called “a function definition” or “a function declaration” or “a function statement”. Usually, developers new to JavaScript have no trouble using this syntax as it closely resembles functions/methods in other popular programming languages.
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.
Function expressions
This is when things start to get more interesting in JavaScript. Let’s see how a function expression looks like.
This seemingly simple example can help you take your JavaScript skills to the next level.
- 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.
In the above example, the function on the right-hand side of the assignment operator is often called a “function expression.” They are everywhere in JavaScript. Most callbacks you might have written are often function expressions.
You might have used these function expressions without understanding the underpinnings. But mastering them will give you some secret JavaScript superpowers.
So the important concept to remember here is that functions are almost like any other values in JavaScript. They can be on the right-hand side of an assignment operator, or they can be passed as arguments to other functions.
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!
Thanks for being patient and patience is the most important skill that’s needed to master JavaScript!
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!
- As we saw before, a function statement always starts with the function keyword. Whenever JavaScript sees function keyword as the first word in a valid statement, it expects that a function definition is going to take place. So to stop this from happening, we are prefixing “!” in-front of the function keyword on line 1. This basically enforces JavaScript to treat whatever that’s coming after “!” as an expression.
- 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.
Next time whenever you are creating a bunch of variables and functions in global scope that no one uses outside your code, just wrap all of that in an IIFE and get a lot of good JavaScript karma for doing that. Your code will continue to work, but now you are not polluting global scope. Also you are shielding your code from someone who may change your globals accidentally, or sometimes intentionally!
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.
- JavaScript always does scope lookups from the current function’s scope and keeps searching in higher scopes until it finds an identifier. When we pass document on line 3, that’s the only time when we are doing a scope lookup beyond local scope for the document. Any references in the IIFE to document will never need to be looked up beyond the local scope of the IIFE. Same applies to jQuery as well. Performance gain by this may not be huge based on how trivial or complex the IIFE code is, but still it’s a useful trick to know.
- Also, JavaScript minifiers can safely minify the parameter names declared in a function. If we did not pass these as parameters, minifiers don’t minify direct references to document or jQuery as they are outside the scope of this function.
Classical JavaScript module pattern
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.
(If you want to master closures, please read my amazing and viral tutorial on closures: Learning JavaScript Closures through the Laws of Karma.)
Now that’s a really powerful JavaScript pattern that you have learned. It combines the power of both IIFEs and closures.
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 when it’s obvious to the JavaScript engine that it’s a function expression, we don’t technically need those surrounding parentheses as shown below.
In the above example, function keyword isn’t the first word in the statement. So JavaScript doesn’t treat this as a function statement/definition. Similarly there are other places where you can omit parenthesis when you know it’s an expression.
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!
I love writing these JavaScript tutorials. It’s so much fun to write them. But they do take a lot of time and effort to polish and publish. If you found this tutorial useful, you can “clap” to show your appreciation and help recommend this tutorial to others. Please follow me here on Medium and also on Twitter to get updates whenever a new article is published.
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.
Now, that was a lot of JavaScript, take a deep breath and take a break from JavaScript by reading my latest post.
My other JavaScript tutorials here: