Javascript Interview Preparation CheetSheet

Javascript Interview Preparation CheetSheet

Javascript Interview Topics - Hoisting

The most frequently asked questions in Javascript Interviews are basically from some core topics of Javascript, which are Call Stack, Scope Chain, Multi-Paradigm, Single Thread , Hoisting, Prototype-based Object Oriented and 'this' -keyword.

Let's discuss Hoisting in Javascript today.

I wrote an article about the Execution context, Kindly look into that article first in order to understand Hoisting mechanism in Javascript. Execution context article

We know that in the execution context there are always three parts.

  • Variable Environment
  • Scope Chain
  • this - keyword

I have also written an article about the Scope chain, So, the link is here in case you need it. Scope Chain Article

Now we have to look at the Variable Environment.

In Javascript, we have a mechanism called hoisting.

It basically makes some types of variables accessible or usable in the code before they are actually declared in the code.

Basically, the code is scanned for variable declarations before it is executed. This happens during the so-called creation phase of the execution context then for each variable that is found in the code, a new property is created in a variable environment object.

That's the hoisting really works!

Now, let's dig deep.

Hoisting does not work the same for all variable types. Now let's see the way hoisting works for function declarations, variables defined with var, let or const and function expressions, and also arrow functions.

Compilation (8).png

In this reference image, we can see that function declarations are actually hoisted and the initial value in the variable environment is set to the actual function. That means we can use function declarations before they are actually declared in the code because they are stored in the variable environment object, even before the code starts executing. function declarations are block scoped (Only in strict mode otherwise functions).

Next, variable declarations with var are also hoisted, but hoisting works in a different way here. unlike functions, when we try to access a var variable before it's declared in a code, we don't get the declared value but we get undefined. And this type of weird behavior is a common source of bugs in JavaScript. So, in modern JavaScript we almost never use var.

On the other hand let and const variables are not hoisted. I mean, technically they are actually hoisted but their value is basically set to un-initialized. So, there are no value at all to work with. we can say that these variables are placed in a so-called Temporal Dead Zone or TDZ which makes it so that we can't access the variables between the beginning of the scope and to place where the variables are declared. So, if we attempt to use a let or const variable before it's declared, we get an error, also keep in mind that let and const are block scoped. So they exist only in the block in which they were created. And all these factors together are basically the reason why let and const were first introduced into the language, and why we use them now instead of var in modern JavaScript.

Now, on function expression and arrow function, it depends if they have been created using var or const or let. Because keep in mind that these functions are simply variables. So they behave the exact same way as variables in regard to hoisting. This means that a function expression or arrow function created with var is hoisted to undefined. But if created with let or const, it's not usable before it's declared in a code because of the Temporal Dead Zone.

Now let's look at the example code now.

Compilation (9).png

In this image code example, we're gonna look at the 'lastName' variable. It is a const so it's scoped only to this if block and it's gonna be accessible starting from the line where it's defined.

Because there is this Temporal Dead Zone for the 'lastName' variable. It's basically the region of the scope in which the variable is defined, but can't be used in any way. So it is as if the variable didn't even exist. If we still tried to access the variable while in the TDZ like, actually do in the first line of this if block, then we get a reference error telling us that we can't access 'lastName' before initialization.

But if we tried to access a variable that was actually never even created, like in the last line here where we want to log x, then we get a different error message saying that x is not defined at all.

This means that 'lastName' is in fact in the Temporal Dead Zone where it is still un-initialized, but the engine knows that it will eventually be initialized because it already read the code before and set the 'lastName' variable in the variable environment to un-initialized.

So, in a nutshell, the variable is only safe to use after the TDZ Temporal Dead Zone.

So, why is it so? Why TDZ used in Javascript?

The main reason that the TDZ was introduced in ES6 is that it way easier to avoid and catch errors. Because using a variable that is set to undefined before it's actually declared can cause bugs and might be hard to find. So accessing variables before declaration is bad practice and should be avoided. And the best way to avoid it is by simply getting an error when we attempt to do so. That's exactly what a Temporal Dead Zone does.

That's it for all Hoisting, it's just an oversimplification of this complex mechanism.