What is scope?
Scope can be defined as the space in which variables and statements are accessible. It makes it possible to have variables with the same name without colliding with one another and prevents outer scopes from having access to inner scopes.
In Javascript we have three types of scope: global scope, function/local scope and block scope. Let's learn what those are:
Global scope
- The default scope
- There is only one global scope in the program
- It is the top scope that englobes the entire code
- The declarations inside this space can be accessed anywhere in the code
Take a look at the example below. The function getAge
is able to reference the age
that is outside the function but located in the global scope.
Local scope or Function scope
- Created by a function invocation
- The declarations inside the function are only accessible there
Let's look at another example. Below we are printing the result of getAge
function. The age
constant is located inside the function scope so we are able to return it, but when we try to print it from the global scope we get a reference error. This happens because outer scopes (in this case the global scope) cannot access the inner scope (local scope) created by getAge
.
Block scope
- The space between a pair of curly braces (if block, for block, etc.)
- Applicable to
let
andconst
- Declarations are only accessible inside the block
In the example below we are able to print the variable msgOne
but not constant msgTwo
. As mentioned before const
and let
are block scoped so they are only visible inside the block, in this case inside the if
statement. On the other hand var
is function scope so can be accessed within the function.
Scope chain
Take a look at the code below. What is printed to the console? The answer is My name is Joana, I'm from Brazil and I speak brazillian portuguese
. But what makes it possible for the displayInfo
function to access the constants from outside your scope?
const language = 'brazillian portuguese'
const name = 'Ana'
function displayIntroduction() {
const name = 'Maria'
const country = 'Brazil'
function displayInfo() {
const name = 'Joana'
console.log(`My name is ${name}, I'm from ${country} and I speak ${language}`)
}
return displayInfo()
}
displayIntroduction()
Before we dive into how, let me briefly talk about the execution context. This concept won't be covered in this article but it is important to explain what it is in order to make it easier to understand scope chain. So, execution context is an environment in which javascript code is evaluated and executed. When the code first starts running it creates a global execution context and a function execution context is created on each function invocation. The scope chain of this code looks similar to this:
Each execution context has a scope chain. It consists of the variables and objects referenceable by the execution context. Besides the variables and objects it has a property called outer
that stores the reference to the parent's scope chain.
When the displayInfo
function is executed and reaches name
it searches for it in the local scope chain, finding Joana
as the value. The same process happens for country
but it is not in the local scope.
So, how is javascript able to reference it?
When the constant is not found in the local scope javascript reaches to the parent's local memory accessible by the reference stored in outer
, getting Brazil
as the value.
Last but not least, the same thing happens to language
in this case the javascript engine goes all the way up the scope chain reaching the global scope to find the constant, retrieving the value brazillian portuguese
. It is important to know that the scope chain works only one way, from the inner scope to the outer scopes, making it impossible for the global execution context to have access to country
, for example.
Also know that since the global execution context is the top context the outer
points to null
, so if the variable wasn't there it would be implicitly declared, if not in strict mode, or an error would be returned.
Conclusion
Scope and scope chain are fundamental topics to understand how the javascript engine process and executes code.
To recap:
- There are three types of scope: global scope, function scope and block scope
- Scopes make possible to have variables with the same name without colliding with each other
- Variables and objects in inner scopes are not accessible from outer scopes
- Scope chain consists of the variables and objects referenceable by the execution context
Thanks for reading :)
Top comments (3)
This is fabulous article, really thank you so much sir. But I had doubt, what exactly you mean by this "objects referenceable by the execution context". I just don't understand that quoted text, if anyone can explain it please do.
In JavaScript objects are non-primitive or reference data type, During the memory creation phase of execution context, Reference Data type , Store in Heap Memory space, to connect with Execution context it provides reference.
Great explanation.