Daniel Matthew

Closures 101

I updated this post on the 16th February in order to clarify my writing and thoughts.

What is a closure?

In computer science:

a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be "closed over" its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself.

A higher-level definition is that

A closure is a function defined within another scope that has access to all the variables within the outer scope.

And just in case, think of it as:

...like keeping a copy of the all the local variables, just as they were when a function exited.

Closures are a strange concept to get to grips with, but once this core concept is understood they're relatively easy to understand: a closure is created when a developer accesses variables outside of the immediate lexical scope.

An example of a closure in action

function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}

x = makeAdder(5);
y = makeAdder(20);

x(6); // 11
y(7); // 27

JSFiddle demo

What happens in a closure?

When makeAdder is called, a new scope is created with one property: a - the argument passed to the function. It also returns the anonymous function declared within it. This returned function maintains a reference back to that original scope. This scope will persist and escape being garbage collected until there are no more references to that function.

Take a look at what happens when we log x:

function(b){
  return a + b;
}

So when we call x and pass an argument, that's going straight into the anonymous function makeAdder returned the first time. Because we know a closure is a combination of a function and its scope

Since we are then able to all y, we discover that we have ended up with two different copies of makeAdder's local variables: one in which a is 5, and another where a is 20.

When would I use a closure?

The technique is often used to prevent against contaminating higher levels of scope - data is kept tucked away. Along these lines, a closure can be used to help practise encapsulation: an object can return its public methods and variable, while keeping those intended to be private hidden and inaccessible to the rest of the codebase.

You may have taken advantage of one without realising it, as they're a key concept when implementing an 'Immediately-Invoked Function Expression' (IIFE). Using an IIFE within a module, as per the Module Pattern, ensures that the module is self-contained.

An intelligent developer will

use closures to create additional scopes that can be used to group interrelated and dependent code in a way that minimises the risk of accidental interaction.

Useful reading

Daniel is a front-end developer at Talis, with an interest in accessibility, performance, and web components.