We are now going to have a look at something like magic, and then explain what is happening (decoding the magic).
Lets us consider one program here and see what the output is –
If I ask what is the output of the above program, you would just say that this is very obvious… why are you even asking this? The output is obviously going to be 10. And it is absolutely right.
But, let’s now change some things. Have a look at the below program, and let’s predict the output now –
Now, there is a possibility that you might think, ok… we are going to get an error because we are trying to access the variable even before we have created it. It is pretty easy to guess! But… it is not the thing. Let’s have a look at the output for this case.
Well, instead of getting an error, we got undefined. But how is it so? This means before even creating the variable, we are trying to access it, and we are not getting an error, but just undefined. For another example, let’s try to get rid of lines involving variable declarations. After that, let’s have a look at the output for that case.
As you can see, earlier, we were at least not getting any error, but now, since the variable that we are trying to access does not even exist in the program, in this case, we are going to get a ReferenceError, stating that the variable we are trying to access is not defined.
So, this makes clear, that the undefined thing and the not defined thing are different.
Let’s come back to our previous example, where we were able to access the variable even before we created it. This is a different thing in that we were not getting the value that is actually there, but we were able to access it, and here is the point. Let me show you one more thing. We can execute some functions, even before declaring them. Have a look at this –
So, if we try to run this, we are absolutely getting no problem, and the code just runs fine.
Well, hoisting is a behavior of moving the variable, function declarations, on the top of the scope. If this definition is not completely digestible, let’s discuss this in quite detail, so that we are able to become familiar with it.
What we mean by hoisting is just taking the declarations to the top of the scope. So, if you observe the below program, we can easily determine that ok… the variable is created first, and then we try to access it, which is totally fine.
First of all, in the creation phase, it will go through the code and do the necessary memory allocations, and some other things that would be used in the run time.
So, in the creation phase, the function declarations and the variables are allocated some memory. For the variables, the memory is allocated, and the initial value assigned is undefined(in case the variable is made with the var keyword). The functions are also made available in the memory to be accessed. So, the functions are available for execution even before the code runs.
This is the reason why we were able to call the function before even declaring it (because the call is at the runtime, and the function declaration into memory before that). A similar reason, for why we are able to access the variable before the variable is declared(that thing is different, that we get the value undefined for the variable, since the declarations only are hoisted, and not the assignments).
As you can see, the above code is perfectly fine. But, let’s say that this time, we are creating an anonymous function. Let’s have a look at this –
If we try to run the above program, we will get an error, saying that this function is not a function. Strange right? We have made it as a function only, but still, it is not hoisted. Well, this is because of the fact that only declarations are hoisted, and not the assignment. So, the variable thisIsaFunction was made in the memory, but with a value undefined. At this moment, the assignment is not done, so it is not known whether it contains a function actually.
Well, you know that the variables can be created with let and const keywords as well. So, what we saw above, for the variables created with the var keyword, is it the same for the variables created with let and const? Let’s have a look at some examples –
Well, if we now have a look at the output, we get the value as undefined, which does make sense, since we know that we have created a variable, but not assigned anything to it, so the value here is going to be undefined. But now, let’s try to access the variable created with the let keyword, even before the declaration(similar to what we did previously).
If we try to have a look at the output in the console, it comes out to be something like this –
As you can see, we got an error saying, cannot access some variables before initialization. This does mean that some variable is not initialized yet, so, we cannot use them. When it comes to const, we are going to get some things as output. (well, you will have to assign some value to the constant that we have created, in this case)