π Introduction
In programming, scope means the area in which a variable can be used or accessed. If you try to use a variable outside its scope, you will get an error. Two common types of scoping are Lexical Scoping and Dynamic Scoping. JavaScript follows lexical scoping. Letβs understand both in detail.
π What is Lexical Scoping?
Lexical Scoping (also called Static Scoping) means that the scope of a variable is decided by the location of the variable in the written code. In other words, where the function and variable are written decides which variables can be accessed.
A function can access variables defined inside it.
A function can also access variables defined in its outer functions.
It cannot access variables defined in inner functions.
Example:
let name = "Alice";
function outer() {
let greeting = "Hello";
function inner() {
console.log(greeting + ", " + name);
}
inner();
}
outer();
// Output: Hello, Alice
Here, inner()
can use both greeting
(from outer) and name
(from global). This happens because of lexical scoping.
π What is Dynamic Scoping?
Dynamic Scoping means the scope of a variable is decided by the function call stack at runtime. This means the variable is searched in the calling function, not where the function was written.
π Important: JavaScript does not support dynamic scoping, but some other languages (like Lisp, older scripting languages) do.
Hypothetical Example:
let greeting = "Hi";
function outer() {
let greeting = "CSahrp Corner";
inner();
}
function inner() {
console.log(greeting);
}
outer(); // In dynamic scoping β "CSahrp Corner
inner(); // In dynamic scoping β "Hi"
If JavaScript used dynamic scoping, the output would change depending on which function calls inner().
But since JavaScript uses lexical scoping, the output will always be based on where the function is defined, not who calls it.
βοΈ Key Differences between Lexical and Dynamic Scoping
1. Definition
2. Support in JavaScript
3. Behavior
Lexical Scoping: The output is always predictable because it depends on the code structure.
Dynamic Scoping: The output may change depending on who calls the function, making it harder to understand.
4. Use Cases
Lexical Scoping: Useful for closures, callbacks, and writing clean code.
Dynamic Scoping: Found in some older languages but not suitable for JavaScript.
π§© Why JavaScript Uses Lexical Scoping
JavaScript uses lexical scoping because it makes code more predictable and easy to debug. By just looking at the code, a developer can know which variables are available to a function.
Closures in JavaScript also depend on lexical scoping.
Closure Example:
function makeCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
Here, the inner function continues to access the variable count
even after makeCounter()
has finished executing. This is possible because of lexical scoping.
π Summary
Lexical and Dynamic Scoping are two ways to decide how variables are accessed. JavaScript uses lexical scoping, meaning that a variableβs scope is decided by where it is written in the code. Dynamic scoping, on the other hand, decides scope based on who calls the function at runtime. Since lexical scoping is more predictable and easier to manage, JavaScript follows it by default, and this also enables powerful features like closures.