Closures are functions or references to functions that hold within their scope non-local variables. This variables endure beyond their existence outside of these functions scope. These variables are therefor enclosed within the lexical-scope of that functions.
This is particular useful for JavaScript where with every function call (even if the same is called recursively) a new execution context is created, and an automatic garbage collection throws out all contexts with no reference. For a detailed explanation Jim Ley’s description of closures in JavaScript has proven itself as a great resource.
To create closures in JavaScript one has to assign a reference to a nested function (inner function) declared within a different function object. The garbage collection than can not remove the execution context of that function, as there still exists an object holding a reference to it. And this inner function holds the scope of the outer function even though that function has already returned. Here is a simple example to explain:
function counterscope() { var counter = 0; function f() { return counter++; } return f; } var count = counterscope(); var count2 = counterscope(); console.log(count()); // 0 console.log(count()); // 1 console.log(count2()); // 0 -> references different/new scope console.log(count()); // 2
counterscope() returns a declaration of an inner function f , which as to the lexical-scope of JavaScript inherits the scope of counterscope() , namely the variable counter . This means f holds a reference to counter, while counter may no longer exist in the context of counterscope() as this function returns. count is the property holding the reference to f and we can execute it repeatedly changing the variables state in the local context. count2 also holds a reference to f with it’s own scope, as we can see upon execution of count2().
This post can only provide you with a rough understanding of closures in JavaScript. Having a good understanding of closures, can be very important to JavaScript development as it is such a common and useful pattern. The same probably holds true for the Prototype concept of JavaScript. Reading through the here provided references should help you getting comfortable with closures.
But how are closures useful? For example you can use the inherit context as a cache storing the result of a long calculating function or implementing private members to JavaScript objects as described here: Private Members in JavaScript
Let’s see how we could implement a local function cache with closures and JavaScript, and Python.
var calc = (function executeFunc(){ var cache = []; return function calc(x){ if(cache[x]){ console.log("Cache hit: "+ cache[x]); return cache[x]; } cache[x] = x+10; return cache[x]; } })(); console.log(calc(10)); console.log(calc(20)); console.log(calc(10)); // cache hit console.log(calc(30)); console.log(calc(20)); // cache hit
Here the closure cache[] is used to store the results of our very complicated calculation. This example is also slightly different from the previous as we here use an anonymous function ()() to build up the enclosing scope. Let’s now see how we can implement the same functionality with Python.
Closures in Python work quit similar to JavaScript. A function declaration is returned from a different function object. The caching example from JavaScript in Python looks as follows:
def calcFunc(): cache = {}; def calc(x): if x not in cache: print "Cache miss." cache[x] = x + 10 return cache[x] return calc count = calcFunc() print count(10) // Cache miss. 20 print count(10) // 20
So what we see here is the use of closures in Python. As if in JavaScript a function declaration is returned which captures the scope of the enclosing function that returns it.
Further Readings:
- Closures (Wikipedia)
- Javascript Closures
- Why use “closure”?
- JavaScript: The Definitive Guide 6th
(amazon)
- Programming Python
(amazon)