10. Call Stack , Lexical scoping, Closures in javascript
Call Stack
The call stack is a data structure that keeps track of function calls in LIFO (Last In, First Out) order.
How It Works?
When a function is called, it's pushed onto the stack.
When the function finishes execution, it's popped off the stack.
The stack continues this process until it's empty.
Execution Context
The Execution Context is the environment where JavaScript code is executed.
» It is a wrapper that contain global object and this variable
Lexical Scoping
Lexcal scoping is the ability of a nested function to access the variable decalred in thier parent function scope
» If nested function defination written outside but called inside any other function then variable search for outside fucntion defination scope not a function call.
Example:
//Lexical scoping
var a = 10;
function fn1 (){
console.log("Inside fn1",a); // function defination of fn1 , access value of varibale a outside its fucntion defination
}
function fn2(){
var a=20;
function fn3(){ // access the value of a in its parent function scope
console.log("Inside fn3",a)
}
fn1(); // function call of fn1
fn3();
console.log("Inside fn2",a);
}
fn2();
/* Ouput
Inside fn1 10
Inside fn3 20
Inside fn2 20
Closures
A closure is created when inner function(nested) remember and continue to access variables from its lexical scope even after the outer function has finished executing.
✅ Closures = Function + Lexical Scope
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const counter = outer(); // outer function return inner function
counter(); // 1
counter(); // 2 // count updated, inner function remeber previous count defined in outer()
counter(); // 3
inner()
remembers count
, even after outer()
has finished executing.
How can closures be useful?
✅ Answer:
Closures are useful for:
Data Privacy (Encapsulation)
Creating Private Variables
Memoization & Caching
Event Handlers & Callbacks
Interview Questions
What will be the output of following code ?
function a() { console.log("A"); b(); } function b() { console.log("B"); c(); } function c() { console.log("C"); } a(); console.log("End");
Output:
A
B
C
End
The Call Stack order:
a()
→b()
→c()
c()
finishes first, thenb()
, and finallya()
, before"End"
is printed.Write output ?
console.log(foo()); function foo() { return "Hello"; } console.log(bar()); var bar = function() { return "World"; }; /* Output Hello TypeError: bar is not a function
function outer() { let a = "Hello"; function inner() { let a = "World"; console.log(a); } inner(); console.log(a); } outer(); /* World Hello
What will be the output ?
function counter() { let count = 0; return function () { count++; console.log(count); }; } const c1 = counter(); c1(); c1(); const c2 = counter(); c2(); c2();
Output :
1
2
1
2