A closure is a first-class function that refers to (closes over) variables from the scope in which it was defined. If the closure still exists after its defining scope ends, the variables it closes over will continue to exist as well.
A closure is a first-class function that refers to (closes over) variables from the scope in which it was defined. If the closure still exists after its defining scope ends, the variables it closes over will continue to exist as well.
JavaScript closure
A basic example of closure in JavaScript can be shown with a counter:
function increment () {
var count = 0;
return function () { // returning function
count++; // increment the count
return count;
};
}
var foo = increment(); // foo is now a closure function, where count = 0
foo(); // calls the closure which yields 1
The reason why increment
is considered to be a closure is because it's a local variable. In this case, count
is persisting when assigned to the variable foo
. This persistence occurs because the context of foo
is taken from increment
when it's declared.
The key point with a closure is that the environment of the function is 'closed' to a hosting object.
var bar = increment(); // bar is now another closure function, with count initialized to 0
bar(); // calls the closure which yields 1, not 2.
jQuery closures
A more practical example of a closure is the jQuery
library. jQuery itself is one big closure. It's declared like this:
var jQuery = (function() { // Here is the closure
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'.
return new jQuery.fn.init( selector, context, rootjQuery );
},
...
}) ( window );
Let's take a deeper look at this. jQuery's closure is actually an immediately invoked function expression or a closure that is immediately called. Let's take our original increment example and represent it in the form that jQuery uses:
var foo = (function () {
var count = 0;
return function () {
count++; // Increment the count
return count;
};
}) ();
foo(); // Yields 1
At first glance, this looks quite a bit different from our original example, but take another look. The only difference is that this example is wrapped in parentheses. (function () {...}) ();
. These parentheses are returning the result of what's inside of them.
The first parentheses are returning a function that has count = 0
. This is the same as calling increment()
in our first example and the second set of parentheses is calling the returned function.
Resources
- How do JavaScript closures work?
- What is the difference between a 'closure' and a 'lambda'??
- What are 'closures' in .NET?
For a history of closures as a programming language construct see the Wikipedia Closure page.
In Ruby, closures are called blocks.