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.