Gyaan

Closures

intermediate scope functions lexical-environment

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

One of the most common uses of closures is data privacy. We can create variables inside a function that cannot be accessed from outside.

createCounter() scope
let count = 0  (private)
increment()
count++ ✓
getCount()
return count ✓
Outside: count ✗ ReferenceError
function createCounter() {
  let count = 0; // private variable, not accessible from outside
  return {
    increment: function() {
      count++;
    },
    getCount: function() {
      return count;
    }
  };
}

const counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount()); // 2
// console.log(count); // ReferenceError: count is not defined

A very common interview question is closures inside loops. When we use var in a loop with setTimeout, all the callbacks share the same i variable, so they all print the final value instead of each value.

// Problem with var
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
// Output: 3, 3, 3 (all reference the same i)

// Fix with let (block-scoped, creates new binding each iteration)
for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
// Output: 0, 1, 2