Monday, June 24, 2024

Scopes in JavaScript

In JavaScript, scope determines the accessibility (visibility) of variables, functions, and objects in some particular part of your code during runtime. There are several types of scope in JavaScript:

1. Global Scope:
Variables declared outside any function have global scope. They are accessible from anywhere in the code.
In a browser, global variables become properties of the 'window' object.

var globalVar = "I'm a global variable";
function globalScopeTest() {
  console.log(globalVar); // Accessible
}
globalScopeTest();
console.log(globalVar); // Accessible

2. Function Scope:
Variables declared inside a function are local to that function and cannot be accessed from outside the function.
Function scope applies to variables declared with 'var'.

function functionScopeTest() {
  var functionVar = "I'm a function-scoped variable";
  console.log(functionVar); // Accessible
}

functionScopeTest();
console.log(functionVar); // Uncaught ReferenceError: functionVar is not defined

3. Block Scope:
Block scope is created by 'let' and 'const' inside blocks delimited by '{}' (like in loops, 'if' statements, etc.).
Variables declared with 'let' or 'const' are only accessible within that block.

{
  let blockVar = "I'm a block-scoped variable";
  console.log(blockVar); // Accessible
}

console.log(blockVar); // Uncaught ReferenceError: blockVar is not defined

4. Lexical Scope:
Lexical scope means that inner functions have access to variables and functions declared in their outer scope.
This is determined by the physical placement of the function within the nesting of scopes.

function outerFunction() {
  var outerVar = "I'm an outer variable";
  function innerFunction() {
    console.log(outerVar); // Accessible due to lexical scoping
  }
  innerFunction();
}

outerFunction();

5. Module Scope:
Variables declared inside an ES6 module are scoped to that module.
This means they are not accessible from other scripts unless explicitly exported and imported.

// myModule.js
const moduleVar = "I'm a module-scoped variable";

export function getModuleVar() {
  return moduleVar;
}

// main.js
import { getModuleVar } from "./myModule.js";
console.log(getModuleVar()); // Accessible

Scope Chain and Closures

Scope Chain:
When trying to access a variable, JavaScript first looks in the current scope. If it does not find the variable, it looks in the outer scope, and so on, up the chain until it reaches the global scope.

Closures:
A closure is a function that retains access to its lexical scope, even when that function is executed outside its original scope.
This allows functions to maintain state across different invocations.

function makeCounter() {
  let count = 0;

  return function () {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

Understanding these different scopes is crucial for managing variables and avoiding common issues like variable shadowing, where a variable in a local scope can unintentionally override a variable in an outer scope, and memory leaks caused by unintended references in closures.

No comments:

Post a Comment

Hot Topics