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
78
votes
6 answers

In Python 2, how do I write to variable in the parent scope?

I have some code like: def example(): # other logic omitted stored_blocks = {} def replace_blocks(m): block = m.group(0) block_hash = sha1(block) stored_blocks[block_hash] = block return '{{{%s}}}' %…
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
77
votes
6 answers

Assign click handlers in for loop

I'm having several div's #mydiv1, #mydiv2, #mydiv3, ... and want to assign click handlers to them: $(document).ready(function(){ for(var i = 0; i < 20; i++) { $('#question' + i).click( function(){ alert('you clicked ' + i); }); …
Philip
  • 3,470
  • 7
  • 29
  • 42
77
votes
7 answers

"Closures are poor man's objects and vice versa" - What does this mean?

Closures are poor man's objects and vice versa. I have seen this statement at many places on the web (including SO) but I don't quite understand what it means. Could someone please explain what it exactly means? If possible, please include…
missingfaktor
  • 90,905
  • 62
  • 285
  • 365
75
votes
2 answers

Updating closures to Swift 3 - @escaping

I've updated my code to Xcode 8.0 beta 6 but I got stuck with what seems to be about the new non escaping closure default. In the following code Xcode suggests to add @escaping in front of completion: in the first line of the below code, but that…
nontomatic
  • 2,003
  • 2
  • 24
  • 38
75
votes
3 answers

@noescape attribute in Swift 1.2

There is a new attribute in Swift 1.2 with closure parameters in functions, and as the documentation says: This indicates that the parameter is only ever called (or passed as an @ noescape parameter in a call), which means that it cannot …
Dániel Nagy
  • 11,815
  • 9
  • 50
  • 58
73
votes
8 answers

What exactly does "closure" refer to in JavaScript?

I understand what closures are, but I am having some trouble grokking exactly what the term closure refers to. I have seen the term used in many websites, but rarely do they agree on the actual definition of it. Is it the variables that are kept…
Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
72
votes
11 answers

How to inject variable into scope with a decorator?

[Disclaimer: there may be more pythonic ways of doing what I want to do, but I want to know how python's scoping works here] I'm trying to find a way to make a decorator that does something like injecting a name into the scope of another function…
beardc
  • 20,283
  • 17
  • 76
  • 94
70
votes
6 answers

Best pattern for simulating "continue" in Groovy closure

It seems that Groovy does not support break and continue from within a closure. What is the best way to simulate this? revs.eachLine { line -> if (line ==~ /-{28}/) { // continue to next line... } }
talanb
  • 994
  • 1
  • 8
  • 13
68
votes
4 answers

PHP 5.4 - 'closure $this support'

I see that the new planned features for PHP 5.4 are: traits, array dereferencing, a JsonSerializable interface and something referred to as 'closure $this support' http://en.wikipedia.org/wiki/Php#Release_history While the others are either…
jon_darkstar
  • 16,398
  • 7
  • 29
  • 37
68
votes
4 answers

Can you patch *just* a nested function with closure, or must the whole outer function be repeated?

A 3rd party library we use contains a rather long function that uses a nested function inside it. Our use of that library triggers a bug in that function, and we very much would like to solve that bug. Unfortunately, the library maintainers are…
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
67
votes
3 answers

Memory leaks and closures in JavaScript - when and why?

You quite often read on the web that using closures is a massive source of memory leaks in JavaScript. Most of the times these articles refer to mixing script code and DOM events, where the script points to the DOM and vice-versa. I understand that…
Golo Roden
  • 140,679
  • 96
  • 298
  • 425
67
votes
5 answers

Exception: Serialization of 'Closure' is not allowed

So I am not sure exactly what I would have to show you guys, how ever if you need more code please do not hesitate to ask: So this method will set up the initMailer for Zend with in our application: protected function _initMailer() { if…
TheWebs
  • 12,470
  • 30
  • 107
  • 211
66
votes
1 answer

Detailed Explanation of Variable Capture in Closures

I've seen countless posts on how variable capture pulls in variables for the creation of the closure, however they all seem to stop short of specific details and call the whole thing "compiler magic". I'm looking for a clear-cut explanation of: How…
DuckMaestro
  • 15,232
  • 11
  • 67
  • 85
66
votes
3 answers

What is wrong with my javascript scope?

The following alerts 2 every time. function timer() { for (var i = 0; i < 3; ++i) { var j = i; setTimeout(function () { alert(j); }, 1000); } } timer(); Shouldn't var j = i; set the j into the individual…
Naftali
  • 144,921
  • 39
  • 244
  • 303
64
votes
14 answers

setTimeout() inside JavaScript Class using "this"

I am trying to use setTimeout() inside a class function in JavaScript. The setTimeout() is supposed to trigger another method in the same Class, so the function I am passing it is written as window.setTimeout("this.anotherMethod", 4000). That bring…
Dean
  • 7,814
  • 8
  • 30
  • 31