0
function Foo() {
   var num = 1;

   function Bar() {
      num++;
      console.log(num);
   }

   function Dummy() {
      Bar();
   }

   this.func = Dummy
}

let fooInstance = new Foo();
fooInstance.func();  // print 2

what I don't understand is: after new Foo() is called, function Foo() get popped on the stack, any local variables created during new Foo() is called should be destroyed, then how come fooInstance.func() can still read something which has been already destroyed?

or does function Foo() not popped on the stack after new Foo() is called?

  • 1
    _"any local variables created during `new Foo()` is called should be destroyed"_... what makes you think that? – Phil Aug 09 '23 at 00:09
  • 2
    Not exactly duplicates but they help answer the question: [What exactly does "closure" refer to in JavaScript?](https://stackoverflow.com/questions/1801957/what-exactly-does-closure-refer-to-in-javascript) [How are JavaScript closures garbage collected?](https://stackoverflow.com/questions/19798803/how-javascript-closures-are-garbage-collected) – Wing Aug 09 '23 at 00:15
  • @Phil isn't that how the stack works? https://www.javascripttutorial.net/javascript-call-stack/ when a function (like `add` example in the link) finishes execution, it gets popped from from current stack, any local variable in that function also get destroyed – user22155685 Aug 09 '23 at 00:18
  • @Phil thanks for the clarification, just to confirm, does `var num` stored on the stack or the heap? also there is no way for `fooInstance` to access its `var num` , that's why I thought it was just get destroyed when the constructor function finishes – user22155685 Aug 09 '23 at 00:40
  • 2
    @Phil No, this has nothing to do with `new`. The scope with the `var num` (and `Bar` and `Dummy`) lives as long as the `Bar` and `Dummy` functions live. Sure, `Dummy` is currently part of the `fooInstance`, but when you do `fooInstance.func = null` then the scope can be garbage-collected while the instance is not. – Bergi Aug 09 '23 at 00:43
  • 1
    "*when a function […] gets popped from from current stack, any local variable in that function also get destroyed*" - no. Not in JavaScript. The variables persist as long as anything still references them. The tutorial that you linked doesn't even say anything about local variables! Read https://www.javascripttutorial.net/javascript-closure/ instead. – Bergi Aug 09 '23 at 00:46
  • @Bergi thanks for your anwser, just to confirm, if `var num` still persist after `new Foo()` is called, what if there is another function to be called immediately after, then this new function will be on the stack, which can overwrite `var num`? – user22155685 Aug 09 '23 at 00:58
  • 1
    @user22155685 No. The `var num` is not allocated on the stack. It's only referenced by the stack frame, not part of it. See the links Wing has shared above for details. – Bergi Aug 09 '23 at 01:10
  • @Bergi sorry, after reading the link, I am still confused, so does `var num` get allocated on the heap? because of new keyword, an instance is created on the heap, so as var num? – user22155685 Aug 09 '23 at 02:38
  • 1
    @user22155685 Javascript's stack is actually implemented in the C/C++ heap. It's the stack but the stack has been `malloc()` in C++. Don't confuse javascript's stack with C++ stack that javascript is implemented in. And the whole reason why javascript stack cannot be implemented as part of the C/C++ stack is precisely because of javascript's support of closures. See my answer to this question for a more detailed explanation: https://stackoverflow.com/questions/26061856/javascript-cant-access-private-properties/26063201#26063201 – slebetman Aug 09 '23 at 03:17
  • FWIW this is true for all languages that support lexical closures: lisp, Haskell, Python, OCaml etc. – slebetman Aug 09 '23 at 03:19

0 Answers0