Tyrone
Tyrone

Reputation: 13

Difficulty understanding closure example

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)

Upvotes: 0

Views: 66

Answers (1)

Aadit M Shah
Aadit M Shah

Reputation: 74204

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.

Upvotes: 1

Related Questions