I asked a question about Currying and closures were mentioned. What is a closure? How does it relate to currying?
A closure is a function and its scope assigned to (or used as) a variable. Thus, the name closure: the scope and the function is enclosed and used just like any other entity.
According to Wikipedia, a closure is:
Techniques for implementing lexically scoped name binding in languages with first-class functions.
What does that mean? Lets look into some definitions.
I will explain closures and other related definitions by using this example:
function startAt(x) {
return function (y) {
return x + y;
}
}
var closure1 = startAt(1);
var closure2 = startAt(5);
console.log(closure1(3)); // 4 (x == 1, y == 3)
console.log(closure2(3)); // 8 (x == 5, y == 3)
Basically that means we can use functions just like any other entity. We can modify them, pass them as arguments, return them from functions or assign them for variables. Technically speaking, they are first-class citizens, hence the name: first-class functions.
In the example above, startAt
returns an (anonymous) function which function get assigned to closure1
and closure2
. So as you see JavaScript treats functions just like any other entities (first-class citizens).
Name binding is about finding out what data a variable (identifier) references. The scope is really important here, as that is the thing that will determine how a binding is resolved.
In the example above:
y
is bound to 3
.startAt
's scope, x
is bound to 1
or 5
(depending on the closure).Inside the anonymous function's scope, x
is not bound to any value, so it needs to be resolved in an upper (startAt
's) scope.
As Wikipedia says, the scope:
Is the region of a computer program where the binding is valid: where the name can be used to refer to the entity.
There are two techniques:
For more explanation, check out this question and take a look at Wikipedia.
In the example above, we can see that JavaScript is lexically scoped, because when x
is resolved, the binding is searched in the upper (startAt
's) scope, based on the source code (the anonymous function that looks for x is defined inside startAt
) and not based on the call stack, the way (the scope where) the function was called.
In our example, when we call startAt
, it will return a (first-class) function that will be assigned to closure1
and closure2
thus a closure is created, because the passed variables 1
and 5
will be saved within startAt
's scope, that will be enclosed with the returned anonymous function. When we call this anonymous function via closure1
and closure2
with the same argument (3
), the value of y
will be found immediately (as that is the parameter of that function), but x
is not bound in the scope of the anonymous function, so the resolution continues in the (lexically) upper function scope (that was saved in the closure) where x
is found to be bound to either 1
or 5
. Now we know everything for the summation so the result can be returned, then printed.
Now you should understand closures and how they behave, which is a fundamental part of JavaScript.
Oh, and you also learned what currying is about: you use functions (closures) to pass each argument of an operation instead of using one functions with multiple parameters.