According to wikipedia, a closure is:
a technique for implementing lexically scoped name binding in languages with first-class functions.
I don't think this mouthful definition is comprehensible to anybody learning the language. So I decide to break it down and explain it in plain language.
Lexical Scope
Lexical scope = static scope, it refers to
determining a variable's scope based solely on its position within the textual corpus of code.
An example to illustrate this concept:
foo = 1; //a global variable that can be accessed from anywhere within the program
function log()
{
var bar = 2; //a local variable can be only accessed by the function log itself
}
We can determine where foo and bar can be accessed within the program by looking at the code. Thus, the scopes of the variables are determined statically.
To contrast it with dynamic scope:
function log() {
console.log(x); //resolve variable x at runtime (i.e. dynamically)
}
function print(){
var x = getUserInput();
log();
}
The value of x is not determined until runtime. Thus, console.log(x)
has no idea what will be printed out. Also, x is neither a globally variable nor is defined within the log
function. But log
has access to it.
Note: this example above does not work in Javascript because JS does not support dynamic scoping.
So now we understand what the fancy term lexical scope means, let's take a look at the definition of first-class function
First-Class Function
A language supports:
- passing functions as arguments to other functions
- returning them as the values from other functions
- assigning them to variables
- storing them in data structures.
This one is easy to understand:
function isBigEnough(value) {
return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough); // the filter function expects a function being passed in as a parameter
I am not going to provide an example for each bullet point. But you get the idea. Passing, storing and returning functions are very common in Javascript.
Closure
According to this explanation,
Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure 'remembers' the environment in which it was created.
function outer(){
var x = 5; // the so called 'free' variable that can be accessed by inner()
function inner(){
console.log(x);
}
return inner;
}
var test = outer(); // outer() actually returns inner(), thus exposing inner() to the outside world
test(); // output 5
Highlights of this example:
-
inner()
has access to variable x, which is defined outside of it -
var test = outer()
is equivalent ofvar test = inner()
but test has no access tox
- The value of
x
is stored in memory so that any subsequent call oftest()
will print 5
So to summarize what a closure is:
- A function f that is nested within another function
- f accesses variables defined in the outer function
During the research of closure, another term comes up often:
Higher-order function
A function that does at least one of the following:
- takes one or more functions as an input
- outputs a function
So outer()
is an example of a higher-order function because it outputs a function. The Mapfunction of a Javascript array is also a higher-order function because it takes a function as input.