The scope is the execution context of a variable or function. It defines what data it has access to. This concept may seem pretty straightforward, but has some important subtleties.
JavaScript has traditionally had two types of scope: global scope and local scope. The purpose of the scope is to provide access to all variables and functions that an execution context has access to.
When a variable is declared outside of any function it belongs to the global scope automatically and can be accessed from anywhere in the program, be it a function or any block. Also, if desired, in the browser we can create a global variable by declaring it as window.newVariable
at any place in a program.
const nestAnimal = 'crocodilian'; // belongs to the Global scope
function getNestInfo(){
window.eggs = 5; // as well belongs to the Global scope
}
In fact, in the browser, variables in the global scope belong to the global window
object.
JavaScript is a garbage-collected language, it keeps available all variables while executing the program in the context and remove after. Let’s consider the lifecycle of the variable. The variable comes into existence during the execution of the function. The variable is used inside the function and then the function ends. At that point this variable is no longer needed, so its memory can be reclaimed and JavaScript remove this variable from the memory. But global variables remain in the memory for the all the time the application is running and clogs up it, which slows down the program, also it may cause unexpected name conflicts.
That all means that, whenever possible, you should avoid to defining global variables. They are only truly needed in very specific cases, so be careful with this.
ES6 introduced block-scoped variables using the const
and let
keywords. With these keywords, local scope is created and exists within the innermost block that surrounds it. It could be a function, for
loop, while
block, if
block, etc. Such locally scoped variables can be only accessed from within that block.
Each block has its own execution context which defines what data it has access to, as well as how it should behave. When code is executed in a context, a scope chain is created. It includes all declared variables and functions inside that block, then the data from the containing (parent) context, and so on. This pattern continue until the global context is reached.
Let’s have a look at an example:
let caymanMood = 'calm';
function changeMood(newMood){
if (caymanMood === 'calm'){
caymanMood = newMood;
} else {
caymanMood = 'calm';
}
}
changeMood('happy');
The function changeMood
has a scope chain with two objects in it: its own variable object (arguments object newMood
) and the global context’s variable object caymanMood
. The function has access to caymanMood
because it’s part of its scope chain.
It’s possible to augment the scope chain besides global and local execution contexts. We can do this in two ways.
catch
block in a try...catch
statement.function buildNest() {
const assets = 'grass';
with(reptilian){
const building = ability + assets;
}
return building;
}
with
creates a object that is added to the front of the scope chain, but the thing is when you read the code you can’t know for sure which object exactly will be modified. Will it be the global variable ability
or the variable in this context reptilian.ability
. So the correct execution of the program can’t be guaranteed. Use of the with
statement is not recommended by the MDN web docs as it may be a source of confusing bugs and compatibility issues.
The catch
statement creates a new variable object that contains a declaration for the thrown error object and this error object is added to the front of the scope chain.
With this, you should now have a slightly better understanding of how local and global scope works in JavaScript and how relying on the closest local context possible is a good idea for writing easily readable and maintainable code.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.