Javascript Foundation: Global Variables & IIFE

Why they are bad and how to walk around them

Allan Sendagi
6 min readMar 15, 2020

Global Variables are bad. And you might have wondered why we don't just use global variables all the time.

I mean we can just declare all our variables into the global scope; then whatever functions we use will have access to all those variables.

Wouldn’t that be nice that everything has access to everything? Because now we won’t have to worry about undefined, undeclared variables and having chains. Doesn't all this make our code more complex and harder to understand?

There are a few issues with what's known as polluting the global namespace — having too much data on our global execution environment.

Remember we have limited space. Limited memory. We have already talked about how memory leaks happen when we just have too much stuff in our memory heap that eventually just overflows making things get slower and slower until our browsers crash.

One of the main ways we do that is with global variables. I know you are thinking: But I am only gonna declare a few variables; that won't crash the browser!

There is another issue with global variables and why we want to avoid using them. Let's look at an example:

The issue with global variables is that we can have variable collisions. For example imagine if we have multiple scripts here which as our application gets larger and larger, we have more than one javascript file.

Now let's have a look at what z is?

I have overwritten whatever I had at the top here the z=1 because we had a collision. And the way this works is that in the HTML file, all these script tags get combined essentially into one execution context.

So everything gets bunched up together, everything is on the global execution context and they override each other if there are any duplicates.

Now, this creates a lot of possible bugs. We write different variables and we think that maybe it's safe but how can we know if somebody on another file overwrites one of our variables?

How do we solve this issue then? How can we use what we know now about scope chains to avoid the issue of global variables?

With modern javascript, we have things like ES modules and module bundlers.

But before we had those, Javascript developers used IIFE’s or an immediately invoked function expression.

An IIFE looks like this:

We already know this; we know what the Javascript engine is going to do with this code.

IIFE’s are a common Javascript design pattern used especially back in the day with a lot of popular Libraries such as jquery and backbone js. The idea was that if we used this pattern, we could place all library code in one local scope to avoid any namespace collisions.

So with the brackets wrapped we are saying that, hey, this isn't a function declaration, its a function expression. So the Javascript engine won't see function as the first item on the line, instead, it's going to see these brackets.

Let’s run this anonymous function and see what happens. We get undefined.

But what if I use a function declaration and call it afterward immediately?

Here I am going to get a syntax error. You can’t really call a function declaration immediately afterward. But with a functional expression, you can.

But what's the benefit of doing this?

Since the anonymous function within this IIFE is a function expression, and it's not being assigned to any global variables, no global property is really being created. And all the properties created inside of the IIFE are going to be scoped there. It’s only going to be available inside the IIFE but not outside.

I can't really access a. a is not defined.

An immediately invoked function expression allows us to call immediately — as Javascript is executing. It’s going to define what the function is and right afterward with the bracket run it.

Its going to create a new variable environment, a new execution context that's going to have our own variable scope. And this allows us to attach private data that can be accessed by the global execution context. Because as we know by now the chain runs downward.

Let’s try something here before we move on. What if I move the brackets inside? Will anything change?

It doesn't. We are still following the rules of Javascript. We have a function expression because of the parenthesis. And right after the compiler looks through the code, it immediately calls it.

Now, imagine I create another function here. I am going to call it a that simply returns 5.

And if I run it, I get 5. This makes sense.

But all of a sudden, there is namespace pollution. I create another function a that returns ‘hahaha’

So that when I run it:

So how can we use IIFE’s to solve this problem?

This is how it worked back in the day before we had ES modules, something we will see later on.

I can create a variable let's call it script1. And within this function, because this is a function expression, I can wrap it in brackets and immediately invoke it.

Now instead of returning 5, I am going to create my function again, and this function a() will now return 5. Now, all we need to do is just return from here an object with a as a function.

So that if I run a again:

I get hahaha. But now within my script1.a:

I have access to a because script1now returns an object that contains this a function for me.

Now the interesting thing with this is we still have a global namespace. We still created this script1 global variable.

But the good thing is we just have one global variable. And this variable can be one object that contains many properties that we might want to use. And it only pollutes the global namespace once.

More importantly, we are attaching this private data to a function that creates fresh environments for us. It executes and it only allows us to return whatever we want from this function.

An IIFE takes advantage of what we learned about scope. It enables us to attach private data to a function and creates a fresh environment for us so that we don't pollute our global execution context.

Because as we start to get more and more Javascript files, we want to make sure that we can wrap things in a function and scope things into their own environments and minimize the amount of data that we place on the global execution context.

>>>This keyword

--

--

Allan Sendagi

Technology will save Homo Sapiens from extinction. I document my journey learning these technologies https://www.linkedin.com/in/allansendagi/