2

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

enter image description here

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?

Sam
  • 1,381
  • 4
  • 30
  • 70
  • Because `a()` *finished executing*. Once complete, it gets removed from the call stack - done. When you invoke `b()` (via `x()(`) you're doing a *new* function call which completes and returns `c` (assigning it to `y`). – VLAZ Apr 11 '20 at 12:54
  • @VLAZ so if the function has finished the execution it will get removed even if it had entered the stack first?? and can you please confirm that if my understanding of stack is correct ?? – Sam Apr 11 '20 at 12:56
  • The stack is LIFO, yes [I've wrote about it before](https://stackoverflow.com/questions/39459236/understanding-event-queue-and-call-stack-in-javascript/39459913#39459913). If you have something like `a = () => b()` then calling `a()` will push `a` to the stack, then `b` once `b` is resolved, you're back to the stack frame for `a` and once that finishes, you're out back to the previous stack frame (if any). However, you effectively have `a =() ={}` and `b = () =>{}` then calling them after each other so you don't get nested stack frames for them. – VLAZ Apr 11 '20 at 13:03
  • Closures are about scope chains. They have nothing to do with the call stack. – Bergi Aug 21 '21 at 14:22

1 Answers1

1

closure is all about accessing variables from the scope chain or lexical environment. In the example given above

let x = a() => x's output is function b(){given code}; let y = x() => y's output is function c(){given code};

when a() is done executing , our call stack will be empty. So everything will be removed from stack. Now say after thousand line of codes we suddenly want to run our function y().

we have our y as

function c() {
 let son = 'son'
      return `${grandpa} > ${father} > ${son}`
}

at this point of time , if we invoke y(), an execution context of c will be created but will have it has nothing in call stack to reference for $grandpa and $father. But still it will print correct output because of closure that even if the functions are returned, the variables which will be refenced by inner functions will not be garbage collected , they will be store somewhere so that can be used later. This is closure.

miorey
  • 828
  • 8
  • 19