Jules Manson Jules Manson - 11 days ago 11
Javascript Question

What is missing from this description for nested functions and closures at Mozilla Developer Network?

I feel like there is something missing from it. Here it is:

Nested functions and closures

You can nest a function within a function. The nested (inner) function is private to its containing (outer) function. It also forms a closure. A closure is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).

Since a nested function is a closure, this means that a nested function can "inherit" the arguments and variables of its containing function. In other words, the inner function contains the scope of the outer function.

To summarize:


  • The inner function can be accessed only from statements in the outer
    function.

  • The inner function forms a closure: the inner function can use the arguments and variables of the outer function, while the outer
    function cannot use the arguments and variables of the inner
    function.



The following example shows nested functions:

function addSquares(a,b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
a = addSquares(2,3); // returns 13
b = addSquares(3,4); // returns 25
c = addSquares(4,5); // returns 41


Since the inner function forms a closure, you can call the outer function and specify arguments for both the outer and inner function:

function outside(x) {
function inside(y) {
return x + y;
}
return inside;
}
fn_inside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give it
result = fn_inside(5); // returns 8
result1 = outside(3)(5); // returns 8

Answer

Closures are definitely a topic that is confusing at first, but really it boils down to this:

  1. ANYTIME you have a nested function, you technically have a closure.

  2. Just because you have a closure doesn't necessarily mean that your code will be affected in any significant way.

3. When a nested function relies on variables declared in a higher function (ancestor function) AND the nested function will have a lifetime that is LONGER than the function where those relied on variables were declared, you have a closure situation that needs understanding.

Those variables (used in the nested function, but declared in the higher order function, a.ka. free variables) cannot be garbage collected when the function in which they were declared completes because they are needed by the nested function which will outlive its parent/ancestor. This "outliving" can be caused by the nested function being returned to an even higher order caller by the nested function's parent or the nested function is assigned to another object (like a DOM object).

When this happens, a closure is created around the free variable and that variable's scope is now shared by any other in-memory function that relies on it as well. This causes a shared scope and is usually where confusion by a function that was supposed to get its own value does not. In those cases, modifying the inner function to receive a COPY of the ancestor's free variable can solve this confusion.