Scopes, Hoisting, and Closures are terms you will eventually have to deal with in your JavaScript codes. So, don't wait until you get an error you don't understand, and keep reading this post!
Before defining what is Hoisting and Closure, we first need to understand how scopes work in JavaScript.
Scopes
If you google the definition of "Scope" you will find that it is "the extent of the area or subject matter that something deals with or to which it is relevant". In simpler terms, a scope is an extent in which something is important.
Talking in terms of JavaScript, the scope is the area in which variables and functions are accessible. There are two major scopes: Global and Local
A) Global Scope
The global scope is the one where all other scopes can reach. Any variable or function declared in this scope, is accessible in any part of the code. Also, It is the first scope you can state variables and you can think of it as the father of all scopes.
In the above example, you can see that the outerVariable
can be accessed inside the foo()
function. Also, the variable is stated outside of any variable, so it is declared in the global scope. Also, the function foo
is also declared on the global scope. So, you can access that function anywhere in your script.
You realized that we thought of the inside of the function as another scope?
B) Local Scope
There are different types of local scopes, exactly three types: Function, Block, and Module.
a) Function Scope
Every time you declare a function, it creates its scope. So, anything declared inside a function is only accessible inside the function.
The insiderVariable
does not belong to the Global Scope, so it can only be accessed in the scope of foo()
b) Block Scope
In JavaScript, a group of statements arranged inside curly brackets ( {} ) is considered a block statement. These groups have their scope too. So, anything stated inside isn't available in outer scopes.
Another example of a block scope are conditional statements:
c) Module Scope
Any variable stated inside a JavaScript module can only be accessed inside it unless you export them. So every module has its scope too.
For this example, first, we are going to create a module that exports a function
Next, we are going to import this module inside our main JS and test the function
As you can see, the function sayHello()
can access the str
variable because it belongs to the same scope but is not available in our importing module.
But we exported the function to our main JS, so now sayHello()
belongs to this scope. Doesn't it seem weird that it can access the str
constant?
Closures
Well, scopes are not the only reason why the function sayHello()
can access the str
variable, closures are involved too!
In simple terms, closure is the capability that functions have in javascript to access the variables defined in the parent scope. This scope is bundled with the function.
In the previous example, sayHello()
can access str
in another module because the variable is defined in the father scope and closures allow the function to access it.
Also, if you declare a function inside another one, the child can access the father function scope.
Hoisting
Now that you know about scopes, we can talk about Hoisting. It is the default behavior in which variable declarations are moved to the top of their scope.
First, let's get clear that the only variables that are affected are the ones declared with var
and with function
. So, const
and let
are not affected by the hoisting. Second, declaration and initialization are different steps.
In order to understand this, let see this example:
The first time we execute foo()
we should get a ReferenceError
, instead, we are getting undefined
. This is the magic of the hosting!
This is how the code would have look after the hoisting:
As we said before, the declaration of the variable a
is moved to the top of the scope, so when we first call the function foo()
the variable has already been declared but not initialized, that why we get an undefined
Also, Hoisting is the reason why you can execute functions in the same scope before we have declared:
Wrap-Up
- There are four different types of scopes: Global, Function, Block, and Module.
- The difference between each scope is where you can access a variable in the script.
- The closure is the capability that functions have to access the variables stated in their parent scope.
- Hoisting is a default behavior where
var
andfunction
declarations are moved to the top of their scope.
I recommend that you experiment with these concepts on your console to understand them better and if you have any questions ask me down on the comments section! 😬
Top comments (0)