JavaScript Closures

 Reading time ~3 minutes

Heads up: this article is over a year old. Some information might be out of date, as I don't always update older articles.

Introduction

In this new post I’m going to talk about “closures”. Just like [hoisting]({{ site.url }}/javascript-hoisting/), closures are a key concept to JavaScript, since they allow to create functions that bind the variables within a scope. Closures are usually used to build callback functions.

A good definition is available on the Mozilla Developers Network website, on which this post is entirely based.

Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.

Let’s start with a first example, to better understand what we are talking about:

function init() {
    var name = "Foo";
    function nowDisplay() {
        alert(name);
    }
    nowDisplay();
}
init();

The init() function creates a new local variable called name and defines an internal function called nowDisplay. This function has visibility on the variable declared and initialized in the outside function. The code is really intuitive and it is an easy example of functional scoping, in which nested functions can access to external variables.

Now we can edit the previous example in the following way:

function makeDisplay() {
    var name = "Foo";
    function nowDisplay() {
        alert(name);
    }

    return nowDisplay;
}

var display = makeDisplay();
display();

This code behaves exactly like the previous one (you can try it on jsFiddle). The only difference is that the internal function is returned by the outer function, before its exectution. Intuitively one may expect that, after the execution of makeDisplay, the inner variable name would be erased from the stack (like C-languages) and it couldn’t be referenced by display anymore. However running the code shows that the variable can still be used.

This feature is what really characterize closures. The display variable holds the makeDisplay function and every other variable visible to the function during the closure’s creation. Here’s another example:

function increment(base) {
    this.base = base;
    return function(value) {
        return base + value;
    }
}

var addTo5 = increment(5);
var addTo14 = increment(14);

alert(addTo5(5)); // output: 10
alert(addTo14(3)); // output: 17

The increment function in this case is an example of function factory, a functions that adds a specific value to the passed argument. This particular function is used to build two new functions (addTo5 and addTo14) that sets, in their respective environment, the values 5 and 14 as base (first operand of the addition). addTo5 and addTo14 in this case are closures.

It’s important to remember that internal variables are passed by reference and not by copy:

function say33() {
    var num = 32;
    var showAlert = function() {
        alert(num);
    }
    num++;
    return showAlert();
}

var show33 = say33;
show33();
comments powered by Disqus

JavaScript Hoisting

Introduction

In this post I am going to talk about JavaScript. Recently I rediscovered this programming language, after a …