Published on Jan 22 2023
Last updated on May 03 2023
To explore the landscape of JavaScript safely, it is crucial to understand the concept of scopes. Scopes are the territories in which our variables live and thrive. Today, we'll journey through this realm, exploring the different types of scopes and understanding how to wield them effectively.
The scope of a variable determines where it can be accessed and used within your code. There are three types of scope in JavaScript:
Global Scope
Function (Local) Scope
Block Scope
Let's dive into each of these and learn how they function!
Variables declared in the global scope can be accessed from anywhere in your code. Think of global scope as the open wilderness where all functions and blocks can freely access the variables roaming about.
To declare a variable in the global scope, you simply need to define it outside of any function or block.
globarScope.js
1let globalVar = "I'm a global variable!";23function showGlobalVar() {4console.log(globalVar);5}67showGlobalVar(); // Output: "I'm a global variable!"8
However, exercise caution when using global variables. Overusing them can result in unintended consequences, as they can be accessed and modified anywhere in your code. It's best to keep variables as local as possible.
Function scope, also known as local scope, confines variables within the boundaries of a function. These variables can only be accessed within the function they are declared in, effectively keeping them hidden from the outside world.
functionScope.js
1function localScopeExample() {2let localVar = "I'm a local variable!";3console.log(localVar);4}56localScopeExample(); // Output: "I'm a local variable!"7console.log(localVar); // ReferenceError: localVar is not defined8
In the example above, localVar
is only accessible within the localScopeExample
function. Attempting to access it outside of this function results in a ReferenceError
.
Block scope is a more recent addition to JavaScript, introduced with the let
and const
keywords in ES6 (ECMAScript 2015). Variables declared with let
or const
are confined to the block they are declared in, such as a loop or an if
statement.
blockScope.js
1if (true) {2let blockVar = "I'm a block-scoped variable!";3console.log(blockVar);4}56console.log(blockVar); // ReferenceError: blockVar is not defined7
In this example, blockVar
is only accessible within the if
statement. Attempting to access it outside of this block results in a ReferenceError
.
Scopes can be nested within one another, creating a hierarchy of variable accessibility. Inner scopes can access variables from outer scopes, but the reverse is not true.
scopeNesting.js
1let outerVar = "I'm an outer variable!";23function outerFunction() {4let innerVar = "I'm an inner variable!";56function innerFunction() {7console.log(outerVar); // Output: "I'm an outer variable!"8console.log(innerVar); // Output: "I'm an inner variable!"9}1011innerFunction();12}1314outerFunction();
In this example, the innerFunction
can access both outerVar
and innerVar
, as they are in the outer scopes. However, if we try to access innerVar
from outerFunction
or the global scope, we'll encounter a ReferenceError
.
scopeReferenceError.js
1console.log(innerVar); // ReferenceError: innerVar is not defined23function anotherFunction() {4console.log(innerVar); // ReferenceError: innerVar is not defined5}6
Hoisting is a JavaScript mechanism that moves variable and function declarations to the top of their respective scopes during the compilation phase. This can lead to some unexpected behavior, especially when it comes to variables declared with var
.
Here's an example of how hoisting can cause confusion:
scopeHoisting.js
1console.log(hoistedVar); // Output: undefined2var hoistedVar = "I'm a hoisted variable!";
Despite hoistedVar
being declared and initialized after the console.log
statement, the code doesn't throw a ReferenceError
. This is because the variable declaration is hoisted to the top of the scope, while the assignment stays in place. The code is interpreted like this:
scopeHoisting.js
1var hoistedVar;2console.log(hoistedVar); // Output: undefined3hoistedVar = "I'm a hoisted variable!";
To avoid hoisting-related issues, it's a good practice to use let
and const
instead of var
, as they have block scope and are not hoisted in the same way.
Understanding scopes in JavaScript is essential for managing variable accessibility and avoiding common pitfalls. Remember these key points:
Global scope is accessible from anywhere, but use it sparingly.
Function (local) scope confines variables within a function.
Block scope, introduced with let
and const
, confines variables within a block.
Inner scopes can access variables from outer scopes, but not vice versa.
Be aware of hoisting when using var
, and consider using let
or const
instead.
With these concepts in mind, you're well-equipped to navigate the realm of JavaScript safe and sound.
Written by Alissa Nguyen
FollowAlissa Nguyen is a software engineer with main focus is on building better software with latest technologies and frameworks such as Remix, React, and TailwindCSS. She is currently working on some side projects, exploring her hobbies, and living with her two kitties.
Learn more about me
If you found this article helpful.
You will love these ones as well.
Built and designed by Alissa Nguyen a.k.a Tam Nguyen.
Copyright © 2025 All Rights Reserved.