Questions tagged [closures]

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

For a history of closures as a programming language construct see the Wikipedia Closure page.

In Ruby, closures are called blocks.

8908 questions
279
votes
10 answers

Why aren't python nested functions called closures?

I have seen and used nested functions in Python, and they match the definition of a closure. So why are they called "nested functions" instead of "closures"? Are nested functions not closures because they are not used by the external world? UPDATE:…
Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
238
votes
6 answers

Anonymous recursive PHP functions

Is it possible to have a PHP function that is both recursive and anonymous? This is my attempt to get it to work, but it doesn't pass in the function name. $factorial = function( $n ) use ( $factorial ) { if( $n <= 1 ) return 1; return…
Kendall Hopkins
  • 43,213
  • 17
  • 66
  • 89
232
votes
5 answers

Javascript infamous Loop issue?

I've got the following code snippet. function addLinks () { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); }; …
Zhu Tao
  • 7,581
  • 9
  • 35
  • 38
220
votes
12 answers

What are 'closures' in .NET?

What is a closure? Do we have them in .NET? If they do exist in .NET, could you please provide a code snippet (preferably in C#) explaining it?
Developer
  • 17,809
  • 26
  • 66
  • 92
216
votes
8 answers

Why does this UnboundLocalError occur (closure)?

What am I doing wrong here? counter = 0 def increment(): counter += 1 increment() The above code throws an UnboundLocalError.
Randomblue
  • 112,777
  • 145
  • 353
  • 547
214
votes
3 answers

When does a closure implement Fn, FnMut and FnOnce?

What are the specific conditions for a closure to implement the Fn, FnMut and FnOnce traits? That is: When does a closure not implement the FnOnce trait? When does a closure not implement the FnMut trait? When does a closure not implement the Fn…
Denilson Amorim
  • 9,642
  • 6
  • 27
  • 31
196
votes
8 answers

var self = this?

Using instance methods as callbacks for event handlers changes the scope of this from "My instance" to "Whatever just called the callback". So my code looks like this function MyObject() { this.doSomething = function() { ... } var self =…
defnull
  • 4,169
  • 3
  • 24
  • 23
191
votes
7 answers

Passing a function with arguments as an argument?

Is it possible to pass a javascript function with arguments as an argument? Example: $(edit_link).click( changeViewMode( myvar ) );
Lucia
  • 4,657
  • 6
  • 43
  • 57
188
votes
3 answers

Closure use of non-escaping parameter may allow it to escape

I have a protocol: enum DataFetchResult { case success(data: Data) case failure } protocol DataServiceType { func fetchData(location: String, completion: (DataFetchResult) -> (Void)) func cachedData(location: String) ->…
Lukasz
  • 19,816
  • 17
  • 83
  • 139
177
votes
5 answers

Swift optional escaping closure parameter

Given: typealias Action = () -> () var action: Action = { } func doStuff(stuff: String, completion: @escaping Action) { print(stuff) action = completion completion() } func doStuffAgain() { print("again") …
Lescai Ionel
  • 4,216
  • 3
  • 30
  • 48
168
votes
11 answers

How should I call 3 functions in order to execute them one after the other?

If I need call this functions one after other, $('#art1').animate({'width':'1000px'},1000); $('#art2').animate({'width':'1000px'},1000); $('#art3').animate({'width':'1000px'},1000); I know in jQuery I could do something…
texai
  • 3,696
  • 6
  • 31
  • 41
161
votes
10 answers

How do lexical closures work?

While I was investigating a problem I had with lexical closures in Javascript code, I came along this problem in Python: flist = [] for i in xrange(3): def func(x): return x * i flist.append(func) for f in flist: print f(2) Note that…
Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
158
votes
8 answers

Store a closure as a variable in Swift

In Objective-C, you can define a block's input and output, store one of those blocks that's passed in to a method, then use that block later: // in .h typedef void (^APLCalibrationProgressHandler)(float percentComplete); typedef void…
Jay Dub
  • 1,682
  • 2
  • 11
  • 7
152
votes
6 answers

How to use Swift @autoclosure

I noticed when writing an assert in Swift that the first value is typed as @autoclosure() -> Bool with an overloaded method to return a generic T value, to test existence via the LogicValue protocol. However sticking strictly to the question at…
Joel Fischer
  • 6,521
  • 5
  • 35
  • 46
135
votes
2 answers

Is this object-lifetime-extending-closure a C# compiler bug?

I was answering a question about the possibility of closures (legitimately) extending object-lifetimes when I ran into some extremely curious code-gen on the part of the C# compiler (4.0 if that matters). The shortest repro I can find is the…
Ani
  • 111,048
  • 26
  • 262
  • 307