Saturday, September 13, 2014

JavaScript Patterns: IIEF - Immediately Invoked Function Expression

The "createWorker" function is interesting. Because it creates in JavaScript what is known as a scope. 
The local variables that we've created inside the function, like "workCount", "task1" and "task2", they are only visible inside the function itself.



We can have function definitions nested inside of other functions in JavaScript. That’s how "task1" can point to a function that is inside of another function that we assigned to "createWorker".

This is great because "task1" can't be visible outside "createWorker". If we try invoke "task1" from the “worker” object.

We’ll get an error “undefined is not a function” on line 22.



That means something like “I don’t know what task1 is. I’ve got undefined for that and you decided to invoke it. That’s not gonna work”.

The only way we can invoke “task1” is because “createWorker” explicitly reference task1 in an object that is returned to the outside world.

But “task1” itself is inside the scope of “createWorker” and it’s not visible to the outside.
And these variables that we have outside of this function definition, including the variable “createWorker” and the variable “worker”, they are also outside the scope and unfortunately it is the global scope.

They are global variables because they are defined outside any other code, or any other function. If you are doing Software Development for a long time, you’ve probably heard that global variables are bad.

They easily become a source of confusion and bugs. But in JavaScript, global variable are beyond bad. They are evil.

Because JavaScript is a dynamically typed language, it’s very easy to overwrite a global variable defined by someone else and vice-versa. So we should try to avoid globals at all cost.


Is there a way to define all the code that we have, executing that code and achieving the same output without create any global variable?

The answer is yes. What if outside of “createWorker” we define a function called “program”, and program is going to wrap up not just “createWorker”, but also the code where we instantiate a “worker” and call “job1” and “job2”.



Right now, we only have one global variable called “program”.


But how do I get to zero global variables?

What if instead of declaring a variable “program” which will be global. What if we just took this function and at the very bottom of the function definition we just add it invoke itself.



There’s one little problem here. JavaScript doesn't particularly like this syntax.

It doesn't like to have an anonymous function that invokes itself. What we have to do is apply an extra left parenthesis before the keyword function and then have a corresponding close parenthesis at the end before the semi colon.



And what we have built is something called in JavaScript circles an Immediately Invoked Function Expression (IIFE).

It’s a function that has code inside that immediately invokes itself. Because all of that code is inside a function we're not creating any global variables.

All the variables that have been defined are local variables inside of that IIFE.


We should use IIFE to avoid create any global variables. A lot of JavaScript libraries use IIFE to control the scope of the variables, to build modules to provide encapsulation and most of all to avoid global variables.

No comments:

Post a Comment