Demystifying JavaScript Closures, Callbacks and IIFEs

Originally published at: http://www.sitepoint.com/demystifying-javascript-closures-callbacks-iifes/

We’ve already taken a close look at variable scope and hoisting, so today we’ll finish our exploration by examining three of the most important and heavily-used concepts in modern JavaScript development — closures, callbacks and IIFEs.

Closures

In JavaScript, a [closure](http://en.wikipedia.org/wiki/Closure_(computer_programming) is any function that keeps reference to variables from its parent’s scope even after the parent has returned.

This means practically any function can be considered a closure, because, as we learned in the variable scope section from the first part of this tutorial, a function can refer to, or have access to –


  • any variables and parameters in its own function scope

  • any variables and parameters of outer (parent) functions

  • any variables from the global scope.

So, chances are you’ve already used closures without even knowing it. But our aim is not just to use them – it is to understand them. If we don’t understand how they work, we can’t use them properly. For that reason, we are going to split the above closure definition into three easy-to-comprehend points.

Point 1: You can refer to variables defined outside of the current function.

function setLocation(city) {
  var country = "France"; 

  function printLocation() {       
    console.log("You are in " + city + ", " + country);  
  }

  printLocation();
}

setLocation ("Paris");  // output: You are in Paris, France

Try out the example in JS Bin

In this code example, the printLocation() function refers to the country variable and the city parameter of the enclosing (parent) setLocation() function. And the result is that, when setLocation() is called, printLocation() successfully uses the variables and parameters of the former to output “You are in Paris, France”.

Continue reading this article on SitePoint

That statement makes no sense any you appear to have a completely wrong idea about closures - since none of your supposed closure examples actually use a closure.

A closure occurs when a variable or function defined inide of the inner function's scope continues to be accessible to the outer function even after the inner function has returned. Just about the exact opposite of what you said.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures where tyour examples match the first example that illustrates lexical scope (not closures) The next example on that page illustrates the creation of a closure by returning the function from the inn er scope without executing it and then executing it later after the scope it was created in has closed. There are further example further down that page.

To create a closure you must return something that references elements with inner scope.

Felgall, the MDN example you're referencing is virtually identical to the article's "Point 2" example.


Okay - I was misled by the completely incorrect description of what a closure actually is and missed that after the first supposed closure example that didn't include a closure that the subsequent examples started to use one. A very confusing article about closures.

There are basically three ways to create a closure

example1 = function(x) {
var myvar1 = x;
return function() {return myvar1;};
}

var aa;
example2 = function(y) {
var myvar2 = y;
aa = function() {return myvar2;};
}

example3 = function(z) {
var bb, myvar3;
bb = function() {return myvar3;};
myvar3 = z;
return bb;
}

Actually the article got it right. A closure is an inner function that has access to an outer function's variables. And in fact the MDN article you referenced says the same.

Inner functions always have access to outer functions variables - a closure is only created if those variables remain accessible after the outer function has closed.

Let's be clear about something first. This isn't the same argument you made above.

The outer function never has access to the inner function's variables. Rather, the inner function has access to the outer function's variables. The article didn't get it backwards, you did.

And finally, I would agree that a closure only seems useful if we use the inner function sometime after the outer has finished, but if we're going to get technical, then the closure is actually created at the moment that we create the inner function.

I agree with that.

My two arguments appear to contradict one another because I was inconsistent in my use of inner and outer. There are actually three levels of functions involved in creating a closure and in my first argument I was using inner to refer to the innermost of the three and outer the middle one. In the second argument I was using inner for the middle one and outer for the outermost.

A closure is not any function. This is just plain wrong. Closure have nothing to do with a function, in theory.

A function in JavaScript is an Object that inherits the function.prototype methods and arguments (apply(), call(), ...)

A closure on the other hand, refers to the execution context of a callable. And here lies the small difference in meaning where a lot of geeks (like me) tend to get 'mad' about. Ofcourse, execution context kind of only makes sense when executing a function. And yes, it says something about 'what do I have acces to'. But understanding the difference makes understanding the 'this' word so much easier. And the methods like .call() and apply() suddenly start to make real sense.

To understand closures you need to understand the scope of a function, which is what the first example is for (it's not an example of a closure).

A closure is a reference to a value created inside the scope of a function but is still available after that function has executed.

Here's a simple example from the Novice to Ninja book:

function closure(){
var inside = "I was created inside the function";
return inside;
}

The value of the inside variable is unavailable outside the closure() function:

inside;
<< Error: "inside is not defined"

But we can create a closure by invoking the closure() function, which will return the value of inside and make it available outside the function:

outside = closure();
<< "I was created inside the function"

More often than not though a closure will be a function that is returned and keeps the reference to variables created in the original function's scope.

Unfortunately that isn't really an example of a closure. That's just a plain old return value.

Yes indeed - the variable being updated has to be situated outside of the function to be considered a closure.

The important aspect of a closure is that an outer function returns an inner function, with that returned inner function retaining knowledge of variables from the outer one.

The Jibbering Closures FAQ I still find to be highly insightful in regard to closures.

function exampleClosureForm(arg1, arg2){
    var localVar = 8;
    function exampleReturned(innerArg){
        return ((arg1 + arg2)/(innerArg + localVar));
    }
    /* return a reference to the inner function defined as -
       exampleReturned -:-
    */
    return exampleReturned;
}

var globalVar = exampleClosureForm(2, 4);

But the point is that the returned value was created inside the lexical scope of another function and would normally be inaccessible outside of that function.

I admit that the example is basic and in most cases a function would be returned to form a closure, but I don't think that's necessary for it to actually be a closure.

All this discussion certainly shows that they are a difficult concept to define!

There's a difference between values and variables. Values don't have scope; variables do. Getting a value outside of a function isn't anything special. But accessing a variable after the point where it normally would have been destroyed is a trick made possible by closures.

As a followup, this is only possible to achieve thanks to the return being a function, as it retains the environment scope in which it was created.

Yes, okay, I concede that in order to have control over the variable that was created then you will need to return it in a function. I still think that the first example in the article and the example I gave are important in building up to demonstrating closures as they demonstrate the scope of a function and the fact that by using the return statement you can access variables created inside another function.

Sorry Daz, but your example is not helpful in regard to closures. The following diagram might help to clarify things.

It's from another useful blog post on Closures

This part sounds fine. Yes, the first example in the article and the example you gave are a fine demonstration of scope.

But this isn't quite right. In this discussion, remember it's important to distinguish values and variables. A return statement passes a value. You're not creating a closure just by returning some value.

Yes I agree with you on this - it's important that if you just return a variable then it's the value of the variable that is returned and not the variable itself, which is what happens if it is returned inside a function. My example wasn't a great example, sorry if it confused anybody.

DAZ

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.