Scope in Javascript basically means the area of code where a particular variable or function is available.
There are 2 types of scopes in Javascript -
- Function Scope
- Block scope
This article will cover both of them in detail and we will try to understand what they mean. If you have prior experience in other languages like Java, Python, etc., you might find it a bit weird, but I hope that everyone will have a clear understanding of how scopes work in Javascript by the end of this article.
P.S. - You can check out the TL;DR at the bottom of the article
Function Scope
Let us begin by guessing the output of this simple example.
function foo() {
if(true) {
var x = 10;
}
console.log(x);
}
foo(); // ??
If you answered undefined or some error, then you'd be surprised to see that this prints 10
to the console.
Let's dive deeper to understand what is going on under the hood.
Understanding the example
When the function foo
is called, javascript creates a new execution context for foo
and puts it on top of the call stack.
Execution context
contains all the variables and functions that are defined inside the function scope. So before the execution of the function starts, it gets all the variables defined in the foo
function(i.e. x) and puts a value of undefined
to them.
Another point to note here is that what we see is
var x = 10;
, whereas the JS engine breaks it into two lines
var x;
andx=10
i.e the variable declaration and function assignment.
This is broken up and put into tp be put into the Abstract Syntax Tree which is outside the scope of this article.
Now as the function continues its execution, it assigns the value 10 to x and then prints it out to the console.
What we encountered here is called Hoisting
, you may have also read about hoisting where people say that while compilation the declarations are moved to the top whereas, in reality, the execution scope just parses the context and keeps the value of all defined variables as undefined
before execution.
In function scope, all the variables declared inside the function can be used at any place inside the function even before they are declared although it is considered a bad practice to use any variable or function before declaring them.
Block Scope
Let's look at a slightly modified version of our last example.
function foo() {
if(true) {
let x = 10;
}
console.log(x); // ??
}
foo();
This time we got a Reference Error
saying x is not defined
. This should have been the expected behavior all along.
Originally JS did not have block scope
and it was introduced to Javascript in ES6.
To understand block scope first, we need to understand what a block is.
{ ... }
-> This is what a block is. A pair of curly braces and everything inside them is a block. Maybe now you understand why we got a reference error while trying to use x in the second example.
But unlike function scope, you are not allowed to use the variables before declaring them. (Because let
and const
are not hoisted)
Note - Both function and block scope have a reference to their lexical environment which is used when a certain variable is not found in the same environment.
TL;DR
Function scope
is when variables defined in an execution context are available throughout the execution context.
Block scope
is when variables defined in a scope are available only in the current scope and not outside the scope even though it is still in the same execution context.
Conclusion
In this article, we discussed the two different kinds of scopes in Javascript and discussed them in detail.
You can learn more about Scopes in this famous book Scopes and Closures by Kyle Simpson.
Top comments (1)
Nicely written. Great job