1

I can't figure out why an unexecuted closure can capture the outer variables.

I do read about some articles about execute context, lexical environment, memory management, but none of these can solve my question:

function foo() {
  var a = 1;
  return function() {
    console.log(a);
  }
}
var f = foo() // line 7
// HERE variable a was been captured

f = undefined // line 10
// HEAE variable a was been released

When the engine execute to line7, the foo execution context was created above global execution context, but after line7 the closure was never been execute, so the closure execution context was never been created, so was the lexical environment. foo execution context was been popped up, the variable a will be released.

I can't find what's wrong with my point. So why and when the variable in closure be captured?

TaoPaipai
  • 256
  • 3
  • 13
  • When would you have expected the variable to be captured if `f()` was called down the line? – Bergi Aug 30 '19 at 07:12
  • The closure is created when you call `foo()`. How can it know that you're never going to use it? – Barmar Aug 30 '19 at 07:21
  • @Bergi One more question: ExecutionContext created at function invoked time or function declaration time? – TaoPaipai Aug 30 '19 at 09:17
  • @Barmar ExecutionContext created at function invoked time or function declaration time? – TaoPaipai Aug 30 '19 at 09:17
  • @TaoPaipai An execution context ("stack frame") is created when a function is called. But a lexical environment ("scope") is captured on the function object when a function is created. – Bergi Aug 30 '19 at 13:07
  • This is probably a duplicate of https://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1 but maybe your question is deeper? – Barmar Aug 30 '19 at 14:13

3 Answers3

0
function foo() {
  var a = 1;
  return function() {
    console.log(a);
  }
}

Function inside function are known as closure.
When one function has another function inside it, and say top level function has some data like 'a' in this case, then all the inner functions will get access to that data, this will happen only if inner function has some reference about those variables.

Let's say if you have 'b' variable beside 'a' and you are not using it anywhere in inner functions this will be simply ignored by javascript. 'Closure' will not hold this value like 'a'.

This is actually where closure gives devs power.
Check out below example -

const test = (num1) => (num2) => console.log(num1*num2);//closure is in action here
var s = test(100)
s(2); // this will give output of 200

Hope this helps.

Thanks.

Durgesh
  • 205
  • 2
  • 9
0

Here is a discussion on bugs.chromium that is related to your question. As per this , even when the else block never executed , reference to an outer object used in function returned by else block is created and stored in heap. It is never garbage collected. Refer to below discussion :-

https://bugs.chromium.org/p/chromium/issues/detail?id=315190

-1

The key point is lexical scope:

Lexical scope is the scope model used by the JavaScript language, which differs to some other languages which use dynamic scope. Lexical scope is the scope defined at lexing time.

Considering this:

var a = 1
console.log(a)

console.log(b)
var b = 2

console.log(c)

You can get the result:

1
undefinded
ReferenceError: c is not defined

So, you can see how JavaScript handling the variables: all variable are defined at lexing time and assignment at runtime. This is what they called hoisting.

Back to the question: closures capture variables at lexing time in which js engine read your code and defined variable and bind them.

Read more about compilation at: https://v8.dev/blog/background-compilation

TaoPaipai
  • 256
  • 3
  • 13
  • 1
    Compile time is not necessarily the same as definition time. The closure captures variables when it is created, not when its body is compiled. – Bergi Sep 01 '19 at 14:22
  • What @Bergi says. This answer is grossly misleading, if not plain wrong. A closure is the runtime representation of a function value. It is created each time a function expression is evaluated. – Andreas Rossberg Sep 01 '19 at 22:10