0

I'm having a bit of trouble understanding how garbage collection happens when function closures are involved. For instance the below JS code implements an adder function using closures:

function adder() {
        var sum = 0
        return function(x) {
                sum += x
                return sum
        }
}

function abc() {
        var pos = adder()
        for (i = 0; i < 10; i++) {
                console.log(pos(i))
        }
}

abc()

Output:

0
1
3
6
10
15
21
28
36
45

Each time the function pos is invoked, the param x is added to sum and the cumulative sum is returned. What I don't understand is, why is the value of sum retained in function adder? Shouldn't the value of sum get garbage collected as soon as the inner function returns (ie, when pos returns).

Instead, each time posis invoked with a new value of x the sum from the previous call is somehow retained in memory. What is going on behind the scene that causes this to happen?

Amal Antony
  • 6,477
  • 14
  • 53
  • 76
  • possible duplicate of http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – Nina Scholz May 22 '16 at 15:10
  • The fact that the function references `sum`, and that there remains a live reference to the function itself, means that the closure won't be garbage collected. That's the whole point of a closure. – Pointy May 22 '16 at 15:19
  • `adder` is called once, where `var sum = 0` would be defined once; `sum` is then local to the anonymous function returned from `adder`; `var sum = 0` is not set a second time – guest271314 May 22 '16 at 15:20
  • @Pointy: But when the inner function with the reference to `sum` returns, will `sum` not be garbage collected? – Amal Antony May 22 '16 at 15:20
  • No, because the variable `pos` is still an active reference to that returned inner function. – Pointy May 22 '16 at 15:21
  • @Pointy Got it, thanks. What I missing out on, was the fact that `pos` is not garbage collected until `abc` returns. – Amal Antony May 22 '16 at 15:22
  • @AmalAntony definitely read that link that Nina Scholz referenced. – Pointy May 22 '16 at 15:22

1 Answers1

2

The magic behind this is the closure :-)

Each time you invoke a function, some memory (called a closure) is set aside for everything that happens inside the function (between the braces { ... }). Additionally, a function can access everything that is defined outside of it.

So, when you invoke your function adder() on line 10, it creates this closure and stores sum in it. Then, adder() returns a function. For this inner function, sum is global, so it can access and modify it inside its body, and the value (being stored in the closure around the function) survives even when the inner function terminates. Even more, the closure is not garbage collected as long as there is a reference to the inner function in your program because JavaScript knows that the inner function might interact with the closure.

To sum it up, a closure is global to inner functions but invisible to the outside world, which makes them very useful for encapsulating parts of a JavaScript application in the browser. In node.js, this aspect is not as relevant because the module concept already performs encapsulation.

Nicole
  • 1,717
  • 1
  • 14
  • 17