DEV Community

Cover image for Function Scopes and IIFE Pattern
Pranav
Pranav

Posted on

Function Scopes and IIFE Pattern

WHY

Consider you've written code like the below at some point. We've declared a var and hope that it still has the same value. Well, right now it looks good.

var ninja = 'Naruto';

// ...

console.log(ninja); // Naruto
Enter fullscreen mode Exit fullscreen mode

But say after a few months a jr. dev comes along and unknowing try to make a change like this.

var ninja = 'Naruto';

// ...

var ninja = 'Sasuke';
console.log(ninja); // Sasuke

console.log(ninja); // Sasuke -- oops!
Enter fullscreen mode Exit fullscreen mode

So, you can easily see the issue here.
We have a naming collision problem.

You may think, we should just use const there. But the problem is not if the variable can be reassigned (because the developer if not aware could just modify your const to var anyways) but we have a naming collision problem.

So, the problem is: We have a problem where 2 different people wanna use the same semantic name for their purposes.

PSEUDO FIX

Since the problem could be thought of as mainly arising due to the declaration of the variable in the same scope. So, the natural fix coming to mind would be, to make use of different scopes, and one simple way to do so could be by wrapping a function around it.

var ninja = 'Naruto';

function anotherNinja() {
    var ninja = 'Sasuke';
    console.log(ninja); // Sasuke
}
anotherNinja();
console.log(ninja); // Naruto
Enter fullscreen mode Exit fullscreen mode

So, now those vars don't seem to collide anymore and the code seems to work well. But now the problem is, we have a named function in the same scope.

So it seems, we didn't solve the name collision problem, we just shifted it to a different variable name.

REAL FIX - IIFE

var ninja = 'Naruto';
(function anotherNinja() {
    var ninja = 'Sasuke';
    console.log(ninja); // Sasuke
})();
console.log(ninja); // Naruto
Enter fullscreen mode Exit fullscreen mode

So, this code pattern you see is called an IIFE pattern i.e. Immediately Invoking Function Expression, which does exactly what it sounds like.

Using IIFE, we're creating a new scope and immediately invoking it.

Another use case: when you want to turn statements into expressions

Consider below example:

var ninja;
try {
    ninja = fetchNinja();
}
catch (err) {
    console.log(err);
}
Enter fullscreen mode Exit fullscreen mode

If you wanna do something like this, since try-catch is a statement it doesn't work in an expression position.
You can do something like this:

var ninja = (try {
    ninja = fetchNinja();
}

catch (err) {
    console.log(err);
})();
Enter fullscreen mode Exit fullscreen mode

Summary

Try to follow "The principle of least privilege" whenever possible.

The principle of least privilege is the idea that any user, program, or process should have only the bare minimum privileges necessary to perform its function.

Leverage the power of function scopes and IIFE patterns to enjoy the benefits of the principle like:

  1. Avoid naming collisions
  2. Restrict code access
  3. Ability to freely refactor code

Top comments (0)