JavaScript

coding learning websites codepractice

JS Basics

JS Variables & Operators

JS Data Types & Conversion

JS Numbers & Math

JS Strings

JS Dates

JS Arrays

JS Control Flow

JS Loops & Iteration

JS Functions

JS Objects

JS Classes & Modules

JS Async Programming

JS Advanced

JS HTML DOM

JS BOM (Browser Object Model)

JS Web APIs

JS AJAX

JS JSON

JS Graphics & Charts

JavaScript Scope


Scope in JavaScript defines where variables and functions are accessible in your code. Understanding scope is essential to avoid naming conflicts, manage memory, and write predictable code. JavaScript has multiple types of scope, including global scope, local (function) scope, block scope, and lexical (static) scope.

Scope also affects closures, variable hoisting, and memory management.

Global Scope

Variables declared outside any function or block are in global scope. They are accessible anywhere in the code, including inside functions.

let globalVar = "I am global"; // Global scope

function displayGlobal() {
  console.log(globalVar); // Accessible inside function
}

displayGlobal(); // Logs: I am global
console.log(globalVar); // Logs: I am global
  • Global variables can be accessed anywhere, but overusing them can lead to conflicts.

Function Scope (Local Scope)

Variables declared inside a function are local to that function. They cannot be accessed outside the function.

function localExample() {
  let localVar = "I am local";
  console.log(localVar); // Accessible here
}

localExample(); 
// console.log(localVar); // Error: localVar is not defined
  • Function scope is one of the primary ways to encapsulate variables in JavaScript.

Block Scope

With the introduction of let and const in ES6, JavaScript supports block scope, meaning variables are confined to the block {} they are defined in.

if (true) {
  let blockVar = "I am block scoped";
  const blockConst = 10;
  console.log(blockVar);   // Accessible
  console.log(blockConst); // Accessible
}

// console.log(blockVar); // Error: blockVar is not defined
// console.log(blockConst); // Error: blockConst is not defined
  • var does not support block scope; it is function-scoped.

if (true) {
  var functionScoped = "I am function scoped";
}
console.log(functionScoped); // Accessible

Lexical Scope (Static Scope)

JavaScript uses lexical scoping, meaning the scope of a variable is determined by its location in the source code.

function outer() {
  let outerVar = "I am outer";

  function inner() {
    console.log(outerVar); // Inner function can access outerVar
  }

  inner();
}

outer(); // Logs: I am outer
  • Inner functions have access to variables of their outer functions, but outer functions cannot access inner function variables.

function outer() {
  let outerVar = "outer";

  function inner() {
    let innerVar = "inner";
    console.log(innerVar); // Logs: inner
  }

  inner();
  // console.log(innerVar); // Error: innerVar is not defined
}

Scope Chain

When JavaScript looks for a variable, it checks the current scope first, then moves outward through the scope chain until it finds the variable or reaches the global scope.

let globalVar = "global";

function outer() {
  let outerVar = "outer";

  function inner() {
    let innerVar = "inner";
    console.log(innerVar);  // inner
    console.log(outerVar);  // outer
    console.log(globalVar); // global
  }

  inner();
}

outer();
  • This hierarchical lookup is called the scope chain.

Hoisting and Scope

Variable declarations with var are hoisted to the top of their function scope, while let and const are hoisted but not initialized, resulting in a temporal dead zone (TDZ).

function hoistExample() {
  console.log(a); // undefined (var hoisted)
  var a = 5;

  // console.log(b); // ReferenceError (let not initialized)
  let b = 10;
}

hoistExample();
  • Functions are also hoisted, allowing you to call them before their declaration:

greet();

function greet() {
  console.log("Hello!");
}

Closures and Scope

Closures occur when a function remembers its outer variables even after the outer function has finished executing.

function outerCounter() {
  let count = 0;
  return function innerCounter() {
    count++;
    return count;
  }
}

const counter = outerCounter();
console.log(counter()); // 1
console.log(counter()); // 2
  • The inner function retains access to count due to lexical scoping and closures.

Best Practices

  1. Prefer let and const over var for predictable block scoping.

  2. Minimize global variables to reduce conflicts.

  3. Use closures intentionally for encapsulation and private variables.

  4. Understand hoisting to avoid unexpected undefined or ReferenceError.

  5. Use nested functions carefully, keeping track of the scope chain.

Summary of the Tutorial

  • Scope defines where variables and functions can be accessed.

  • JavaScript has global, function (local), and block scopes.

  • Lexical scope determines accessibility based on code location.

  • Scope chain is how JavaScript searches for variables.

  • Hoisting affects variable and function availability.

  • Closures allow functions to remember outer variables.

Mastering JavaScript scope is essential for writing clean, maintainable, and bug-free code, avoiding variable collisions, and leveraging closures for advanced functionality.


Practice Questions

  1. Declare a global variable and access it inside a function. Log the value from both inside and outside the function.

  2. Create a function with a local variable and try to access it outside the function. Observe the result and explain why it fails.

  3. Use let inside a block (e.g., an if statement) and try to access it outside the block. Explain the behavior.

  4. Repeat the previous question using var instead of let and compare the difference.

  5. Create a nested function and access a variable from the outer function inside the inner function.

  6. Write a function that creates a closure to maintain a counter variable, and call it multiple times to see the count increment.

  7. Demonstrate the scope chain by declaring a variable in the global scope and another with the same name in a function, then log both inside the function.

  8. Create two functions where one function calls another and accesses a variable from the calling function.

  9. Write code to show that variables declared with const inside a block are block-scoped and cannot be reassigned.

  10. Create a function that contains a variable with the same name as a global variable. Log both values inside and outside the function to show shadowing.


JavaScript

online coding class codepractice

JS Basics

JS Variables & Operators

JS Data Types & Conversion

JS Numbers & Math

JS Strings

JS Dates

JS Arrays

JS Control Flow

JS Loops & Iteration

JS Functions

JS Objects

JS Classes & Modules

JS Async Programming

JS Advanced

JS HTML DOM

JS BOM (Browser Object Model)

JS Web APIs

JS AJAX

JS JSON

JS Graphics & Charts

Go Back Top