GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • JS Tutorial
  • Web Tutorial
  • A to Z Guide
  • Projects
  • OOP
  • DOM
  • Set
  • Map
  • Math
  • Number
  • Boolean
  • Exercise
  • setTimeout
  • Currying Function

This view

  • Original page
  • New address

GeezerVison is showing www.geeksforgeeks.org — Closure in JavaScript - GeeksforGeeks

geeksforgeeks
search icon
  • Courses
  • Tutorials
  • Interview Prep
  • JS Tutorial
  • Web Tutorial
  • A to Z Guide
  • Projects
  • OOP
  • DOM
  • Set
  • Map
  • Math
  • Number
  • Boolean
  • Exercise

Closure in JavaScript

Last Updated : 17 Jun, 2026

A closure is the combination of a function and its lexical environment, allowing the function to access variables from its outer scope even after the outer function has finished executing.

  • Retains access to outer function variables.
  • Preserves the lexical scope.
  • Allows data encapsulation and privacy.
  • Commonly used in callbacks and asynchronous code.
JavaScript
function outer() {
    let outerVar = "I'm in the outer scope!";

    function inner() {
        console.log(outerVar);
    }
    return inner;
}

const closure = outer();

closure();
closure();
  • The function inner() forms a closure by retaining access to outerVar, which is a variable in the scope of outer().
  • Even though outer() has completed execution, inner() still has access to outerVar due to the closure.

Lexical Scoping

Closures rely on lexical scoping, which means a function’s scope is determined by where it is defined, not where it is executed.

  • A function retains access to the scope where it was defined.
  • Inner functions can access outer function variables.
  • Enables closures to “remember” their environment.

Private Variables

Closures allow a function to keep variables private and accessible only within that function, which is commonly used in modules to protect data from being accessed or modified by other parts of the program.

  • Helps achieve data encapsulation
  • Creates private variables
  • Prevents accidental data modification
JavaScript
function counter() {
    
    // Private variable
    let count = 0; 
    
    return function () {
        
        // Access and modify the private variable
        count++;
        return count;
    };
}

const increment = counter();
console.log(increment());
console.log(increment());
console.log(increment()); 

Closures and IIFE

IIFEs (Immediately Invoked Function Expressions) use closures to encapsulate data within a function, keeping it private and preventing access from the outside, which helps create self-contained modules.

  • Data is scoped to the IIFE.
  • Prevents global namespace pollution.
  • Uses closures for data privacy.
  • Useful for creating modular code.
JavaScript
const counter = (function () {
    let count = 0;

    return {
        increment: function () {
            count++;
            console.log(count);
        },
        reset: function () {
            count = 0;
            console.log("Counter reset");
        },
    };
})();

counter.increment(); 
counter.increment(); 
counter.reset();      

Closure and setTimeout

Closures are helpful in asynchronous programming because they preserve access to variables even after a function has finished executing, which is essential for delayed operations like timers or server requests.

  • Retains state for delayed execution.
  • Works well with callbacks and promises.
  • Useful with timers (setTimeout, setInterval).
  • Helps manage async data flow.
JavaScript
function createTimers() {
    for (let i = 1; i <= 3; i++) {
        setTimeout(function () {
            console.log(`Timer ${i}`);
        }, i * 1000);
    }
}
createTimers(); 

Closures with this keyword

Closures can be confusing with the this keyword because this is determined by how a function is called, not where it is defined, so inside a closure it may not refer to the expected object.

  • this is determined by how a function is called, not by closures.
  • Arrow functions inherit this from their surrounding scope.
  • Use bind(), call(), or arrow functions when needed.
JavaScript
function Person(name) {
    this.name = name;
    
    this.sayName = function () {
        console.log(this.name);
    };

    setTimeout(function () {
        console.log(this.name); 
        // In non-strict mode, this refers to the global object.
        // In strict mode, this is undefined.
    }.bind(this), 1000); 
    // Fix with bind
}

const G = new Person("GFG");
G.sayName();

Common Pitfalls

  • Memory Leaks: Excessive use of closures may retain unnecessary references to variables, causing memory issues.
  • Performance Overhead: Overusing closures might lead to larger memory usage due to retained scopes.
  • Issues Inside Loops: Using var inside loops may cause unexpected behavior because all closures share the same variable.
JavaScript
for (var i = 1; i <= 3; i++) {

    setTimeout(function () {
        console.log(i);
    }, 1000);

}

All callbacks share the same i variable created with var, so the output is 4 4 4. Using let creates a new binding for each iteration.

Also Read:

  • Currying Function
Comment

Explore

    JavaScript Basics
    • Introduction3 min read
    • Variables5 min read
    • Operators4 min read
    • Control Statements4 min read
    Array & String
    • Arrays6 min read
    • Array Methods4 min read
    • String5 min read
    • String Methods8 min read
    Function & Object
    • Functions4 min read
    • Function Expression3 min read
    • Function Overloading4 min read
    • Objects4 min read
    • Constructors4 min read
    OOP
    • OOP5 min read
    • Classes & Objects4 min read
    • Access Modifiers5 min read
    • Constructor4 min read
    Asynchronous JavaScript
    • Asynchronous2 min read
    • Callbacks4 min read
    • Promises4 min read
    • Event Loop3 min read
    • Async Await Fuction3 min read
    Exception Handling
    • Error and Exceptional Handling5 min read
    • Errors Throw & Try to Catch2 min read
    • Custom Errors2 min read
    • TypeError Invalid Array.prototype.sort argument1 min read
    DOM
    • DOM8 min read
    • DOM Elements3 min read
    • Custom Events4 min read
    • Addeventlistener5 min read
    Advanced Topics
    • Closure3 min read
    • Hoisting5 min read
    • Scope4 min read
    • Higher Order Functions7 min read
    • Debugging3 min read
    Courses
    • Placement 360 Course2 min read
    • MERN Full Stack Course2 min read
    • DSA and System Design Course2 min read
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.