JavaScript Variable Scope
In JavaScript, scope refers to the visibility and lifetime of variables within different parts of your code. It defines where a variable can be accessed or modified.
1️⃣ Types of Variable Scopes in JavaScript
There are primarily four types of scope:
1.1 Global Scope 🌍
Variables declared in the global scope are accessible anywhere in the script, even inside functions or blocks.
Example:
let globalVar = "I am a global variable";
function printGlobalVar() {
console.log(globalVar); // Accessing global variable
}
printGlobalVar(); // Output: I am a global variable
console.log(globalVar); // Output: I am a global variable
- Variables declared outside of any function or block are considered global and can be accessed anywhere in your code.
1.2 Function Scope 🏠
A variable declared inside a function is local to that function. It cannot be accessed outside the function.
Example:
function exampleFunction() {
let functionVar = "I am inside a function";
console.log(functionVar); // Output: I am inside a function
}
exampleFunction();
// console.log(functionVar); // Error: functionVar is not defined
- The variable
functionVar
can only be accessed insideexampleFunction()
.
1.3 Block Scope 📦 (Introduced in ES6)
Variables declared inside blocks (enclosed by {}
) using let
or const
have block scope. They are only accessible within the block.
Example:
if (true) {
let blockVar = "I am inside a block";
console.log(blockVar); // Output: I am inside a block
}
// console.log(blockVar); // Error: blockVar is not defined
blockVar
is scoped to theif
block and cannot be accessed outside of it.
1.4 Lexical Scope (Static Scope) 🧑🏫
In JavaScript, lexical scope means that the scope of a variable is determined by where it is declared, not where it is called. The inner function can access the variables of its outer function.
Example:
function outerFunction() {
let outerVar = "I am outside";
function innerFunction() {
console.log(outerVar); // Accessing outerVar from outerFunction
}
innerFunction(); // Output: I am outside
}
outerFunction();
- The inner function can access the variables from its outer function, even though it's called inside
outerFunction()
. This is an example of lexical scoping.
2️⃣ Variable Declaration: var
, let
, and const
2.1 var
Declaration (Function Scope)
Variables declared with var
are scoped to the nearest function (function scope). If var
is used outside of a function, the variable will have global scope.
Example:
function testVar() {
if (true) {
var varVar = "I am declared with var";
}
console.log(varVar); // Output: I am declared with var (accessible outside block)
}
testVar();
- Even though
varVar
is declared inside anif
block, it is still accessible outside that block becausevar
has function scope.
2.2 let
and const
Declaration (Block Scope)
Variables declared with let
or const
are scoped to the block they are declared in, whether that's a function, loop, or conditional block.
Example (let
and const
):
if (true) {
let blockVarLet = "I am declared with let";
const blockVarConst = "I am declared with const";
}
console.log(blockVarLet); // Error: blockVarLet is not defined
console.log(blockVarConst); // Error: blockVarConst is not defined
blockVarLet
andblockVarConst
are only available within theif
block.
3️⃣ Shadowing
Shadowing occurs when a variable declared in a nested scope (inner scope) has the same name as a variable in an outer scope. The inner variable "shadows" or overrides the outer one.
Example:
let name = "Alice"; // Outer scope
function greet() {
let name = "Bob"; // Inner scope
console.log(name); // Output: Bob (inner variable shadows outer variable)
}
greet();
console.log(name); // Output: Alice (outer variable remains unchanged)
- The inner
name
variable shadows the outername
variable within the function, but does not affect the globalname
.
4️⃣ Hoisting
Hoisting is JavaScript's default behavior of moving declarations to the top of their containing scope during execution.
Hoisting with var
(Function Scope)
Variables declared with var
are hoisted to the top of their function or global scope, but only the declaration is hoisted, not the assignment.
Example:
function testHoisting() {
console.log(myVar); // Output: undefined (declaration is hoisted, but assignment is not)
var myVar = "Hello";
console.log(myVar); // Output: Hello
}
testHoisting();
Hoisting with let
and const
(Block Scope)
Variables declared with let
and const
are hoisted, but they remain in a temporal dead zone until they are initialized. Accessing them before initialization will result in a ReferenceError.
Example:
function testLetConstHoisting() {
// console.log(myLet); // Error: Cannot access 'myLet' before initialization
// console.log(myConst); // Error: Cannot access 'myConst' before initialization
let myLet = "Hello from let";
const myConst = "Hello from const";
console.log(myLet); // Output: Hello from let
console.log(myConst); // Output: Hello from const
}
testLetConstHoisting();
5️⃣ Closure
A closure is a function that "remembers" its lexical scope, even when the function is executed outside that scope.
Example:
function outer() {
let outerVar = "I am outside";
return function inner() {
console.log(outerVar); // Accessing outerVar from outer function
};
}
const closureFunc = outer();
closureFunc(); // Output: I am outside
- The inner function has access to the outer function's variables even after the outer function has executed. This is because of closures.
🚀 Summary of Variable Scopes:
Scope | Description | Example |
---|---|---|
Global Scope | Variables declared outside any function or block are in the global scope. | let globalVar = "Global"; (accessible anywhere in the script) |
Function Scope | Variables declared inside a function are only accessible within that function. | function foo() { var insideFunction = "Local"; } (cannot access insideFunction outside foo() ) |
Block Scope | Variables declared with let and const are limited to the block they are in. | if (true) { let blockVar = "Block"; } (cannot access blockVar outside the block) |
Lexical Scope | Functions have access to variables from their outer (lexical) scope. | Nested functions can access variables from outer functions. |
Hoisting | Declarations are hoisted to the top of their scope, but assignments are not. | var x = "Hello"; (can be accessed before declaration, but let and const cannot be accessed early) |
By understanding the scope in JavaScript, you can better manage your variables, avoid errors, and write more efficient code. Let me know if you need further clarification! 😊