Basics of global context and hoisting in JavaScript
Hoisting and global context
In this article, we are going to cover:
- What is the global context?
- What is hoisting in Js?
- What happens in the case of let and const?
Global Context🌏
Let's just say we write the code as:
function sayHello(){
console.log("Hello");
}
sayHello(); //Hello
As we all know it's going to print Hello
.
Now what we are going to do is change the order and write the code as:
sayHello();
function sayHello(){
console.log("Hello");
}
What might surprise you now is that instead of giving an error we get the output as Hello
even if we call the function first and declare it later and this has everything to do with the context in JavaScript.
JavaScript has the bigger context or we can say it as the global context in which everything resides.
To get these even clear let's take an example in the browser.
As you can see we can get the output as a true statement
in the first case as it is obvious but you also get the output as a true statement
in 2nd case. The reason for this is global context as we have discussed earlier which is a window
object in the case of a browser.
PS: You can go to console by visiting any website and right-click and go to inspect and select console.
Hoisting ⛳
MDN says:
Conceptually, for example, a strict definition of hoisting suggests that variable and function declarations are physically moved to the top of your code, but this is not in fact what happens. Instead, the variable and function declarations are put into memory during the compile phase, but stay exactly where you typed them in your code.
The only basic things you need to know about hoisting are these 2 rules, keep that in mind and you will never confused.
- function declarations are scanned and made available.
- variable declarations are scanned and made undefined.
Let's talk about the first rule:
Suppose we write the code as:
function sayHello(){
console.log("Hello");
}
sayHello(); //Hello
The output will be Hello
nothing to be confused about but now let's just say we change the order.
sayHello(); //Hello
function sayHello(){
console.log("Hello");
}
As we talked about earlier the output will be Hello
. This is because of the first rule we said function declarations are scanned and made available in the global context.
Next, let's say we write the function as.
sayHello();
var sayHello = function(){
console.log("Hello");
}
This function expression shows a different result as compared to the function statement. there will be an error saying sayHello
is not a function.
This is because of the 2nd rule we said earlier variable declarations are scanned and made undefined.
As you can see the function is declared as a variable here. So it is made available as undefined
in a global context regardless of being a function it is treated as a variable.
If you change the order you will get the correct output, because now the sayHello is defined.
var sayHello = function(){
console.log("Hello");
}
sayHello(); //Hello
Now let's talk about 2nd rule:
If you write the code like this:
var name="Sam";
console.log(name);
We all know the output will be Sam
. But if you try to access the variable first and then declare
console.log(name);
var name="Sam";
Global context knows that there is a variable name but it is made as undefined
as you know from 2nd rule variable declarations are scanned and made undefined.
so the output will be undefined
.
undefined
is completely different from the error. If you never declare a variable and try to access it, it will give you an error.
What happens in the case of let and const
let and const are hoisted but they behave differently as compared to var
As we have seen earlier var is made undefined
if we try to access it before initialization because it is stored as undefined
in a global context.
But in the case of let
and const
, they stored as undefined but not in a global context but in a different space and this space is inaccessible. That's why if you try to access let or const variable before initializing you will get an error.
There is a concept of Temporal Dead Zone in the case of let.
The variable is said to be in a "Temporal Dead Zone" (TDZ) from the start of the block until the initialization has been completed.
From MDN docs:
let variables cannot be read/written until they have been fully initialized, which happens when they are declared (if no initial value is specified on the declaration, the variable is initialized with a value of undefined). Accessing the variable before the initialization results in a ReferenceError.
If you still have confusion about hoisting you can refer to this: MDN Docs
That's it for this article!