Deep Dive into Immediately Invoked Function Expressions (IIFE) in JavaScript
Rahul

18 Jun, 2023

Deep Dive into Immediately Invoked Function Expressions (IIFE) in JavaScript

JavaScript has some quirky little syntax constructs that seem strange at first but end up being super useful.

One of those is the Immediately Invoked Function Expression or IIFE (pronounced “iffy”). The first time I came across an IIFE, I thought it was some kind of syntax error.

A function that calls itself right after being defined? What sorcery is this?

But it turns out IIFEs are a clever way to create scope in JavaScript and prevent variable pollution in the global namespace, akin to how a Java IDE for Linux keeps your project organized and clean.

They’re used everywhere in JS and once you understand them, you’ll be writing IIFEs all over the place too.

In this article, we’re going to do a deep dive into IIFEs - what they are, why they’re useful, and some interesting ways you can use them in your code.

By the end, you’ll be an IIFE expert and your JS code will be all the better for it. So let’s get started!


What Is an Immediately Invoked Function Expression (IIFE)?

When I first came across Immediately Invoked Function Expressions or IIFEs in JavaScript, I was confused about what they were and why they mattered. An IIFE is a function that runs as soon as it's defined.

It's a function expression that's wrapped in parentheses (), followed by another set of parentheses that invokes the function immediately.

For example:

(function () {

console.log('Hello!');

})();

This syntax creates a function and then executes it right away. But why is this useful? IIFEs allow you to create scope in JavaScript.

Since JavaScript has function scope only, an IIFE creates a scope bubble that encapsulates any variables declared within it.

This pattern is useful because it avoids variable naming collisions in the global namespace.

You can also pass in global objects as arguments to manipulate them without permanently altering them:

(function (global) {

var local = 'some value';

global.foo = true;

})(window);

console.log(window.foo); // true

console.log(local); // ReferenceError! local is not defined outside the scope

Overall, IIFEs are a simple but powerful pattern in JavaScript that every developer should understand. They enable more maintainable code by reducing namespace pollution and allowing safe manipulation of global objects.


Why Use an IIFE in JavaScript?

As a JavaScript developer, IIFEs were a total game changer for me. Why? Because they help keep my code clean and scoped.

  • An IIFE creates a scope that's isolated from the rest of your code. This means any variables declared within the IIFE stay within that scope. Once the function executes, the scope is destroyed, and those variables are gone. This prevents variable name collisions and keeps my global namespace clear.
  • IIFEs also provide encapsulation. The logic inside the IIFE is hidden from the outside world. This modularizes my code and makes it more readable. If I ever need to reuse that logic, I can simply call the IIFE again.
  • IIFEs are also a way to create modules in JavaScript. By passing in global objects as arguments, I can emulate public and private members. The IIFE can modify the global object, but the outside world can only access the properties added to that object.

Overall, IIFEs make my code cleaner, more modular, and easier to maintain. If you're not using them in your JavaScript code already, I highly recommend giving them a try.  

IIFE Syntax and Examples

When I first learned about IIFEs in JavaScript, I was confused by the syntax. But after practicing with some examples, the pattern clicked for me. Here’s a quick primer on IIFEs and how you can use them in your code.


IIFE Syntax

The basic syntax for an IIFE is:


(function () { // function body })();


You're creating an anonymous function and immediately invoking it by adding the () at the end.

This creates a scope that is encapsulated and protects variables from polluting the global scope.

Example 1 - Hiding variables

For example, you can hide variables from the global scope like this:


(function () { var message = "Hello!"; })(); console.log(message); // Undefined

The message variable is not accessible outside the IIFE.


Example 2 - Passing in global objects

You can also pass in global objects as arguments to manipulate them in the IIFE and have the changes persist outside of it:

var num = 1; (function (number) { number++; })(num); console.log(num); // 2

IIFEs took me a while to get used to, but now I use them all the time in my JavaScript code to encapsulate logic and avoid namespace collisions.

I'd encourage you to practice writing some IIFEs yourself to get comfortable with the syntax.


Common Uses of IIFEs

When I first started learning JavaScript, IIFEs confused me.

Why wrap a function in parentheses and invoke it immediately? But as I've grown as a developer, I've come to appreciate how useful IIFEs can be.

Encapsulation

One of the biggest benefits of IIFEs is encapsulation. By wrapping your code in a function, you avoid polluting the global namespace.

This keeps your variables and functions from conflicting with other scripts.

For example:


(function () { var message = "Hello!"; function sayHello() { console.log(message); } sayHello(); })(); sayHello(); // Undefined - sayHello is not defined outside the IIFE

The sayHello() function and message variable are encapsulated within the IIFE and not accessible globally.

Scope

IIFEs also provide scope for your variables and functions. Anything declared within the IIFE stays within the IIFE.

This can be useful when you want to keep variables and functions private.

For example:

(function () { var privateVar = "Hello!"; function privateFunction() { console.log(privateVar); } privateFunction(); // Logs "Hello!" })(); console.log(privateVar); // Undefined - privateVar is not defined outside the IIFE privateFunction(); // Undefined - privateFunction is not defined outside the IIFE


IIFEs are a simple but powerful tool in JavaScript. By encapsulating your code and providing scope, they enable you to keep your code clean and avoid unintended interactions with other scripts.


What is the difference between IIFE and normal function?

When I first started learning JavaScript, I came across IIFEs and didn’t fully understand them.

At their core, IIFEs are just JavaScript functions that run immediately as they are defined.


How IIFEs differ from normal functions

Normal functions in JavaScript are executed when they are invoked, by using the function name followed by ().

IIFEs, on the other hand, are enclosed in ( ) at the end of the function definition, so they run right away.

For example:

// Normal function function doSomething() { console.log('Hello!'); } // IIFE (function () { console.log('Hi!'); })();


The IIFE will print 'Hi!' immediately, whereas the normal `doSomething()` function will not run until it is called.

IIFEs are useful because they don’t pollute the global scope. Any variables declared within an IIFE stay within that IIFE. This can help avoid variable name clashes and keep your code tidy.

Normal functions, on the other hand, declare variables in the global scope unless you use let or const. This can easily lead to unintended variable overwriting and hard-to-trace bugs in larger programs.

So in summary, the main differences between IIFEs and normal functions are:

  • IIFEs run automatically, normal functions run when called
  • IIFEs don’t pollute the global scope, normal functions can
  • IIFEs keep variables contained within them, normal functions often don’t

Hope this helps clarify IIFEs for you! Let me know if you have any other questions.

When Should You Avoid Using an IIFE?

When it comes to IIFEs, there are a few cases where I’d avoid using them.


Global namespace pollution

If you have variables declared within an IIFE, they can actually pollute the global namespace. This happens because var declarations create global variables when not in a function scope. To fix this, use let or const instead of var.


Unnecessary use of IIFEs

Sometimes IIFEs are used when they don’t actually do anything. For example:

(function () { console.log('Hi'); })();


This IIFE simply prints 'Hi' to the console. There's no need for the IIFE here - you can just call console.log('Hi'); on its own.

Nested IIFEs

Having IIFEs within IIFEs within IIFEs can become quite messy and hard to follow. I'd suggest avoiding nesting IIFEs too deeply. If you find yourself with nested IIFEs, it may be a sign your code needs some refactoring to be more readable.


When a function declaration is fine

If you simply have a function you want to call once, a function declaration on its own is perfectly adequate. No need to wrap it in an IIFE. For example:

function sayHi() { console.log('Hi!'); } sayHi();


Here a function declaration is simpler and more readable than an IIFE.

Overall, IIFEs are a useful tool to have in your JavaScript toolbox, but should be used only when truly needed. Avoiding the unnecessary use of IIFEs will make your code more readable and help avoid some unwanted side effects.


Common Mistakes and Best Practices

When using IIFEs in JavaScript, there are a few common mistakes I’ve made in the past and some best practices I’ve picked up along the way.

Forgetting the parentheses

The most common mistake is forgetting the () at the end of the function expression. Without the (), it becomes a function declaration instead of an immediately invoked function expression.

Not using semicolons

Semicolons in JavaScript are technically optional in some cases, but it’s best to include them after your IIFE to avoid errors.

Variable scope issues

Anything declared with var inside an IIFE stays within that scope. Often I’ll declare variables with var at the top of the IIFE to avoid issues accessing those variables later.

Best practices

Some best practices for IIFEs include:

  • Declare all variables with var (or let/const) at the top of the IIFE scope.
  • Use descriptive names for your IIFE to make the code more readable.
  • Pass in global objects as arguments to avoid polluting the global namespace.
  • Nest IIFEs for even more encapsulated scopes.
  • Use IIFEs to create modules in JavaScript.

By following these best practices and avoiding common mistakes, IIFEs can become an extremely useful tool in your JavaScript development. Let me know if you have any other questions!

Conclusion

In the end, IIFE's in JavaScript are a powerful way to encapsulate logic and variables in a local scope. When used correctly, they promote clean coding practices and help avoid unintended interactions with other code.

I hope this deep dive into IIFE's was helpful for you in understanding how they work under the hood in JavaScript. The next time you see an IIFE in the wild, you'll know exactly what's going on.

Happy coding!


Create your Developer Portfolio Right Now on Fueler.

Creating portfolio made simple for

Trusted by 49900+ Generalists. Try it now, free to use

Start making more money