I am trying to understand javascript closure in relation to call stack in javascript.
I came across an example of closure which is
function a() {
let grandpa = 'grandpa'
return function b() {
let father = 'father'
return function c() {
let son = 'son'
return `${grandpa} > ${father} > ${son}`
}
}
}
let x = a();
let y = x();
y();
Now according to my understanding of call stack, when we call the function a() it gets pushed inside the stack, and then when we run function 'b' it gets pushed over 'a' and then function 'c' over 'b'. So according to me it should look something like this
However, the explanation that I came across for this example which shows what closure says that:-
"When we invoked function 'a' what we had in return was function 'b', after returning 'b' function 'a' got popped out of the stack so it's variable environment got removed (the concept of garbage collection - mark and sweep algorithm). But still, function 'c' has the access to variables 'grandpa' and 'father' "
According to my understanding, JS call-stack follows the concept of first in last out( or to say last in first out). So if the call stack follows LIFO then why does a() gets popped out of the stack before c(), shouldn't first c() get popped out followed by b() and then a() ??
I feel that the closure explanation here is opposite to the understanding of my call stack.
I would feel grateful if anyone could explain this closure example along with a call stack?