Skip to Content
Course content

34: Immediately Invoked Function Expressions

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you need to do a quick home repair—say, fixing a leaky faucet. You don't want to buy a massive, permanent workbench and leave it in the middle of your kitchen for the rest of your life. Instead, you bring in a small, portable tool kit, do the job, and then pack everything back up and put the kit away. The kitchen stays clean, and the only thing that remains is the fixed faucet.

An Immediately Invoked Function Expression, or IIFE, is exactly that portable tool kit for your code. It allows you to create a temporary "bubble" where you can do some work, declare some variables, and execute logic, and then immediately vanish. Once the IIFE finishes running, everything inside that bubble—except for whatever you explicitly decided to export—is gone. It doesn't clutter up your global namespace.

Wrapping the logic to protect the global scope

In the old days of JavaScript (and still in many legacy codebases), we didn't have modules. If you declared a variable at the top of your script, it was global. If you were using three different libraries and two of them both decided to use a variable named config, they would overwrite each other, and your app would crash in a way that was a nightmare to debug.

To stop this, I often use an IIFE. Here is a real example: let's say we want to initialize a user's theme preference from local storage, but we don't want the helper variables we use during that process to be accessible to the rest of the application.

(function() {
    const themeKey = 'app_user_theme';
    const savedTheme = localStorage.getItem(themeKey);
    
    if (savedTheme) {
        document.body.className = savedTheme;
    } else {
        document.body.className = 'theme-light';
    }
    
    console.log('Theme initialized successfully.');
})();

Notice that themeKey and savedTheme only exist for the few milliseconds it takes for that function to run. If you try to console.log(themeKey) outside of that block, you'll get a ReferenceError. That's the goal. I've protected my "internal" variables from the rest of the world.

The magic of the double parentheses

You're probably wondering why the syntax looks so weird. Why the wrapping parentheses and the trailing ones? If I just wrote function() { ... }, JavaScript would think I'm trying to declare a named function and would throw a syntax error because I didn't give it a name.

  • The first set of parentheses: These wrap the function and tell JavaScript, "Don't treat this as a declaration; treat it as a function expression." It essentially turns the function into a value.
  • The second set of parentheses: These are the actual "call" operators. Since the first set of parentheses gave us a function value, the second set immediately executes that value.

It's a bit of a syntactic trick, but it's incredibly powerful for keeping your codebase lean.

Passing data into the bubble

Sometimes, you want your IIFE to use a global variable, but you want to "lock it in" locally for a slight performance boost or to make the code more readable. You can pass arguments into an IIFE just like a normal function.

const globalApiUrl = 'https://api.example.com/v1';

(function(apiUrl) {
    // Inside here, we use 'apiUrl' instead of the global variable
    console.log('Connecting to ' + apiUrl + '...');
    // Setup logic here...
})(globalApiUrl);

I personally find this useful when I'm writing a script that needs to be bundled with others. By passing the global in as an argument, it becomes very clear to anyone reading the code exactly which external dependencies the IIFE relies on.




📋 Practical Task

Build a Private Page-View Counter

Your task is to create a page-view counter that keeps track of how many times a "Like" button has been clicked. However, for security and stability reasons, the actual count variable must be private—it should be impossible to change the count by typing a variable name into the browser console.

Requirements:

  • Use an IIFE to encapsulate the logic.
  • Inside the IIFE, create a private variable count initialized to 0.
  • Inside the IIFE, create a function that increments the count and updates the text of an HTML element with the ID counter-display.
  • Attach an event listener to a button with the ID like-btn that triggers the increment function.
  • Ensure that the count variable is not accessible in the global scope.

Starter HTML:

<button id="like-btn">Like</button>
<span id="counter-display">0</span>
Rating
0 0

There are no comments for now.

to be the first to leave a comment.