0

In my attempt to gain an understanding of what a closure is I am having problems understanding the below example provided in the Closure wikipedia article. WikiPage. Could you please help me understand this and possibly provide an easily understandable definition of a closure while doing so.

function startAt(x)
   function incrementBy(y)
       return x + y
   return incrementBy

variable closure1 = startAt(1)
variable closure2 = startAt(5)
Tyrone
  • 13
  • 4
  • Please have a look here: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work I also like this explanation https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Closures – ljnissen Feb 05 '15 at 14:38
  • 1
    Could you be more specific about what you don't understand? Do you understand that `closure1` and `closure2` hold functions, returned by `startAt`? (Related: [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work)) – apsillers Feb 05 '15 at 14:39
  • apsillers, I am slapping my forehead but now the above example makes complete since, thank you. I am still digging through ljnissens links for a better understanding of how to easily define closures. – Tyrone Feb 05 '15 at 21:44

1 Answers1

1

To understand closures you first need to understand scopes. A scope is a lifetime of a variable. A variable declared within a scope is born and it dies when the scope ends. For example:

{              // scope begins
    var x = 0; // variable x is born
    var y = 1; // variable y is born
}              // scope ends, x and y both die

Now, there is a way to keep a variable alive even after the scope that it is declared in ends. In short, it is a way in which variables can cheat death. The way variables cheat death is via closures.

Consider a scope within another scope. The inner scope has access to all the variables declared within the outer scope. However, the outer scope doesn't have access to any variables declared within the inner scope.

{                  // the outer scope has access to x and y only
    var x = 0;
    var y = 1;

    {              // the inner scope has access to x, y and z
        var z = 2;
    }
}

The inner scope has access to z because it is declared in the inner scope. However, it also has access to x and y because those two variables are in the lexical environment (i.e. a parent scope) of the inner scope.

Now consider what would happen if we could move this inner scope outside of the outer scope.

{                  // the outer scope has access to x and y only
    var x = 0;
    var y = 1;

    {              // the inner scope has access to x, y and z
        var z = 2;
    } ---+
}        |
         |
{ <------+         // the inner scope moved outside of the outer scope
    var z = 2;
}

In this case, the outer scope ends. Hence, x and y should die with the outer scope. However, they cannot die because they are still required by the inner scope. When the inner scope is moved outside of the outer scope it becomes a closure for the variable x and y (which are its upvalues) and it keeps these variables alive for as long as it lives itself. That's the general idea of closures.

Now consider the following code:

function startAt(x) {
    return incrementBy;

    function incrementBy(y) {
        return x + y;
    }
}

var closure1 = startAt(1);
var closure2 = startAt(5);

Here, the incrementBy function is an inner function. Hence, it has access to the variable x which belongs to the startAt function. However, when we return incrementBy from startAt we are moving the inner function outside the outer function. Therefore, although x should have died with the return of startAt, it continues living because it is required by incrementBy.

Hence, incrementBy is a closure because it closes over the variable x and keeps it alive for as long as it lives itself; and the variable x is called the upvalue of the closure incrementBy.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299