Reputation: 13
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
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