What is lexical scoping and how does it relate to closures? Lexical scoping क्या है और closures से इसका क्या रिश्ता है?
Lexical scoping means that the accessibility of variables is determined by the position of the variables in the source code (where functions are defined), not where they are called. This is also called static scoping.
// Lexical scoping example
let globalVar = 'global';
function outer() {
let outerVar = 'outer';
function middle() {
let middleVar = 'middle';
function inner() {
let innerVar = 'inner';
// inner() has access to all variables in its scope chain
console.log(innerVar); // 'inner' - own scope
console.log(middleVar); // 'middle' - parent scope
console.log(outerVar); // 'outer' - grandparent scope
console.log(globalVar); // 'global' - global scope
}
inner();
// console.log(innerVar); // ReferenceError - innerVar not accessible
}
middle();
}
outer();
// Scope chain visualization
// inner's scope chain: inner -> middle -> outer -> global
// Lexical scoping is determined at WRITE TIME, not at CALL TIME
let name = 'John';
function sayName() {
console.log(name); // John (lexical scope)
}
function callFromDifferentScope() {
let name = 'Jane';
sayName(); // Still prints 'John' because sayName looks to ITS lexical scope
}
callFromDifferentScope(); // John
// Dynamic scoping (hypothetical) would print 'Jane'
// But JavaScript uses lexical scoping
// How closures use lexical scoping
function createMultiplier(multiplier) {
// Function returns another function
// The returned function 'closes over' multiplier
// It remembers multiplier from its lexical scope
return function(number) {
return number * multiplier; // Uses multiplier from outer scope
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10 - each closure 'remembers' its own multiplier
console.log(triple(5)); // 15
// Real-world: Event handlers and closures
const buttons = document.querySelectorAll('button');
buttons.forEach((button, index) => {
button.addEventListener('click', function() {
// Due to lexical scoping, this closure remembers the index
console.log(`Button ${index} clicked`);
});
});
// Without proper lexical scoping (before let/const)
const handlersWrong = [];
for (var i = 0; i < 3; i++) {
handlersWrong[i] = function() {
console.log(`Handler ${i}`); // All will log 'Handler 3'
};
}
// With lexical scoping (using let)
const handlersRight = [];
for (let j = 0; j < 3; j++) {
handlersRight[j] = function() {
console.log(`Handler ${j}`); // 0, 1, 2
};
}Interview tip: Emphasize that lexical scoping is determined at WRITE TIME (where the function is defined), not at CALL TIME (where it's called). This is why closures work - they capture variables from their lexical scope. Contrast with dynamic scoping (which some languages use) to show the difference.
Lexical scoping का मतलब है कि variables की accessibility source code में उनकी position से determine होती है (functions कहाँ define हैं), न कि कहाँ call होते हैं। इसे static scoping भी कहते हैं।
// Lexical scoping
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();
// Scope chain: inner -> outer -> global
// Lexical scoping WRITE TIME पर determine होता है
let name = 'John';
function sayName() {
console.log(name); // John (अपने lexical scope से)
}
function callFromDifferentScope() {
let name = 'Jane';
sayName(); // अभी भी 'John' print करेगा
}
callFromDifferentScope(); // John
// Closures कैसे lexical scoping use करते हैं
function createMultiplier(multiplier) {
return function(number) {
return number * multiplier;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
// Event handlers में closures
const buttons = document.querySelectorAll('button');
buttons.forEach((button, index) => {
button.addEventListener('click', function() {
console.log(`Button ${index} clicked`);
});
});इंटरव्यू टिप: Emphasize करें lexical scoping WRITE TIME पर determine होता है, न कि CALL TIME पर। यही वजह है कि closures काम करते हैं - वो अपने lexical scope से variables capture करते हैं।
Was this answer clear?