JavaScript  

Difference between Lexical and Dynamic Scoping in JavaScript?

πŸš€ 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

  • Lexical Scoping: Scope is decided based on where the function is written in the code.

  • Dynamic Scoping: Scope is decided based on which function called another function at runtime.

2. Support in JavaScript

  • Lexical Scoping: βœ… Fully supported and default in JavaScript.

  • Dynamic Scoping: ❌ Not supported 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.