Function Scopes And IIFE Pattern

Function Scopes And IIFE Pattern

WHY

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.

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

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!

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

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

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);
}

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);
})();

Summary

Try to follow "The principle of least privilege" whenever possible. 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