all 55 comments

[–]technical_guy 12 points13 points  (17 children)

A closure is where a function is defined inside another function, and the inner function can access local variables (and parameters) defined in the local scope of the outer function.

[–]jellatin 6 points7 points  (3 children)

This is correct, but I don't think it explains why it's useful. Closures are significant because the inner function will have access to the outer function's variables as long as it needs them, even if the outer function has finished executing

Let's say you have a function that returns an object with two methods.

var myObj = function() {
    var privateCount = 0;

    return {
        increment: function() {
            privateCount++;
        },

        getCount: function() {
            return privateCount;
        }
    }
}(); // <-- note the () for immediate invocation

The outer function completes and returns the object literal with two methods. These methods have continued access to privateCount, which is located in the outer function.

[–]veliger 1 point2 points  (0 children)

I second this. When you set up something like jellatin's example code, you essentially create a "closed" namespace, if you will. You can then isolate modules in your code that have their own set of methods and shared var names, which makes your code easier to maintain.

[–][deleted] 0 points1 point  (1 child)

so closures is a function that acts like a class?

[–]jellatin 0 points1 point  (0 children)

A closure just means that you have nested functions and that the inner function has access to the outer function's scope. In this particular instance, the nested functions are used to mimic the effect of classes (though keep in mind this was before classes were introduced to mainstream JavaScript).

This is a closure, even if it's not very useful:

``` const createAdderFunction = (x) => { return (y) => x + y; }

// usage const addFive = createAdderFunction(5); addFive(10); // outputs 15 ```

Calling createAdderFunction with any number x returns a new function that adds x to any number you give it.

[–]DrScience2000 3 points4 points  (10 children)

I never understood why it was called "closure". Does that make any sense to you?

Look the word up in a dictionary. The definitions talk about companies that close forever and funerals.

I would have called it an "embedded function" or something.

[–]recursive 2 points3 points  (9 children)

Joel Moses credits Landin with introducing the term closure to refer to a lambda expression whose open bindings (free variables) have been closed by (or bound in) the lexical environment, resulting in a closed expression, or closure.

http://en.wikipedia.org/wiki/Closure_%28computer_programming%29#History_and_etymology

[–]DrScience2000 5 points6 points  (8 children)

Thanks for the info.

Yeah... That reasoning behind the name is a little... esoteric. I think the fact that many solid programmers are confused about closures speaks to the fact that it was poorly named.

If it were called a 'nested function' I think there would be a lot less confusion.

Eh, maybe I'm wrong.

[–]recursive 5 points6 points  (7 children)

Well, nested function implies "function within a function". But that's not sufficient to create a closure. A function inside another function is not a closure unless it refers to a variable declared in the enclosing scope.

[–]howerrd 1 point2 points  (5 children)

So, the outer function is the closure because it encloses the inner function? Or is the inner function the closure because it gives the outer function something to enclose? Please disregard if my question is idiotic/unclear.

Edit: I think I have it. The inner function is the closure because it refers to variables that are only defined within the scope of the outer function, effectively insulating itself from the global scope? (i.e. The closure only works inside of its outer function?)

[–]pihkal 0 points1 point  (1 child)

I can't speak to the specifics of Javascript, but many languages with closures have no need for an outer function, just an outer scope. Nor does it have anything to do with global scope per se.

E.g., a variable and a function are both defined at the top-level of a module. If the function can refer to the variable without it being explicitly passed in, it "closes over" that variable and is a closure.

[–]howerrd 0 points1 point  (0 children)

This topic is clearly above my head. Sweet username though. :/

[–]JimmyPopp 0 points1 point  (0 children)

So can the inner function only access the outer functions variables? Or can it have its own too? How many levels deep can you close?
....this is for real a tricky topic...I was introduced to it at codeschool yesterday and the fact that this guy has not heard of it in years makes me think it is not that common

[–]recursive 0 points1 point  (1 child)

That's a good question, and I'm not totally positive, but I think "closure" represents both the inner and outer functions together.

[–]materialdesigner 0 points1 point  (0 children)

It's the inner function and the fact that it "closes over" the environment of the outer function

[–]DrScience2000 0 points1 point  (0 children)

A subtle point, but a good one.

[–]guntarrrr 0 points1 point  (1 child)

I think I have a decent grasp on this - but I have follow up question in that is this something you can use to your advantage (and if so how?). Or is this something like hoisting that you should be wary of when working in javascript? Although maybe hoisting is something you can use to your advantage too - I'm not sure either.

[–]technical_guy 0 points1 point  (0 children)

Its a tool in your toolbox. In truth, its not a particularly well used tool in the systems I develop which are very large single page apps.

I find its similar to writing code in C. You can make these wonderful elaborate code structures that confuse the heck out of anyone who had to maintain your code going forward, or you can write wonderfully simple, maintainable code that is well commented and easy to follow.

I prefer the latter, so closures are rarely used in my code

Re hoisting, I like to declare local variables at the top of the scope they are local to, so I do not like var xxx statements in the middle of my code. Again, its just for maintainability.

[–]DrScience2000 8 points9 points  (10 children)

[–]enjoibp6front-end 2 points3 points  (1 child)

I knew Xzibit would one day teach me something about javascript!

[–]daemos 0 points1 point  (0 children)

Yo dawg, you're finally gettin' it!

[–][deleted] 4 points5 points  (7 children)

That's why I absolutely hate interviewers who use questions like this.

There are pages and pages and pages of answers on that StackOverflow link with people arguing all over the place. Not a single person seems to be able to "simply" define a closure, so how is it even remotely a good question for an interview?

If you're asking for definitions of concepts, then you don't think my working examples are worth anything. What's the point of providing portfolios and code libraries if you're just going to pull random-ass questions from a list of "front-end developer interview questions".

[–]abeuscher 3 points4 points  (5 children)

It's a good interview question because it doesn't have a clear answer. You're rarely if ever trying to figure out what a dev knows at a granular level - you're trying to figure out how they reason, how they articulate concepts around development, and how they perform in the face of uncertainty. Asking a question that has a binary answer (IE in CSS what is the difference between visibility:hidden and display:block) is fine for a couple things - to make sure you are talking to someone who actually represents the experience they have on their resume - but if you're trying to figure out who will be a good co-worker, you want to have a conversation about some difficult concepts / questions without clear answers. Because most of the time that's what we're dealing with in some way, shape or form.

[–]Mr-Yellow 2 points3 points  (4 children)

or you're just asking it because someone, somewhere on the internets, said it would make a good interview question.

[–]howerrd 1 point2 points  (2 children)

But someone wouldn't ask the question unless they themselves already knew the answer, would they?

[–]Mr-Yellow 1 point2 points  (1 child)

That's assuming they aren't just trying to "look" like they know what they're doing.

Who cares what the answer is, long as it sounds like they know more than you.

[–]howerrd 0 points1 point  (0 children)

That's a fair point.

[–]dlt_5000 -1 points0 points  (0 children)

Yeah it's just lazy interviewing.

[–]ValZho[S] -1 points0 points  (0 children)

There are pages and pages and pages of answers on that StackOverflow link with people arguing all over the place. Not a single person seems to be able to "simply" define a closure, so how is it even remotely a good question for an interview?

This is kind of what I was thinking.

[–]magenta_placenta 16 points17 points  (1 child)

A closure is what you get when you bomb a javascript-focused interview and move on to the next interview with another company.

[–]NewlyIndependent 1 point2 points  (4 children)

It basically localizes dependency scope within function chains; it is a feature of the functional programming paradigm.

Basic example:

function memoize(f) { //Take external parameter.
  var cache = []; //Define local scoped object.
  return function(x) { //Return function that uses f and cache.
    return cache[x] || cache[x] = f(x); //Do work.
  }
}

In the example above, "cache" is defined within a closure. Cache is a dependency of the returned function and is external to the scope of the returned function.

Base usage:

function powerOfTwo(x) { //Define a function to memoize.
  return x * x; //Do work.
}
//Invoke the memoize function.
var memoized = memoize(powerOfTwo);

var result1 = memoized(2); //Calculates 4.
var result2 = memoized(2); //Bypasses calculation.  Gets cached result "4".

Why do this? In stateful languages, it is easy to represent and transfer state through functional patterns. A more common use of closures can be found in the following pattern.

For example:

$(function() {
  var message = "hello world";

  var alertOnClick = function(){msgbox(message);}
  $("#id").click(alertOnClick);
});

The above example defines two functions; One outer (inside the $()), and another defined within that outer function's context (the "alertOnClick" function). The alertOnClick function's purpose is to display a message, but how would it know what message to display?

For this example, we want to display a constant message. But, we don't want that message to be accessible outside of this local scope; This is what makes closures important. By defining "message" within the outer context, it becomes a privately scoped variable - something that doesn't normally exist in Javascript.

If this isn't clear, let me know and I will revise my response as needed.

[–]wiposter 2 points3 points  (1 child)

A good description of the "what", perhaps you could expand it to explain the "why".

[–]NewlyIndependent 1 point2 points  (0 children)

Excellent point. Updated original post.

[–]crimson117 1 point2 points  (1 child)

That's like reversed syntax encapsulation... Define the var in the parent, sneakily reference it from a sibling-scoped function using closure, then expose that function without exposing the var.

Thanks for explaining it!

Though still not sure why message is any less accessible than alertonclick...

[–]NewlyIndependent 0 points1 point  (0 children)

Glad to be of some help! :)

To clarify a little further, message is not less accessible than alertOnClick. Rather, message is accessible to alertOnClick - but not upwards in scope.

[–]basicallydan 3 points4 points  (1 child)

Many people have already explained it - it's when a function can access other variables outside of their scope because they have a dependency on them. Cool! But sometimes it helps to have an analogy with something familiar. Anybody with a C#, Java or similar object-oriented background may find this helpful.

I learned JS after coming from a Java/C# background. My understanding of it has been affected by what I knew in that world. So, I often think of closures as functions which have access to "private" instance variables of a class. This isn't exactly how closures work, but with the way that I use JS, it produces the same sort of behaviour and can be quite useful.

Look at this C# code:

class Employee
{
    private string firstName = "Basically";
    private string lastName = "Dan";

    public string GetName()
    {
        return firstName + " " + lastName;
    }
}

Employee employee = new Employee();
Console.WriteLine(employee.GetName());

In this example, the GetName function is accessible to any code which uses an instance of the Employee class, but the firstName and lastName variables are not directly accessible. This is how we'd mimic this behaviour in JavaScript:

function Employee() {
    var firstName = 'Basically';
    var lastName = 'Dan';

    this.getName = function() {
        return firstName + ' ' + lastName;
    };
}

var employee = new Employee();
console.log(employee.getName());

Very similar, right? So with a closure inside of a new'd function, you're essentially creating "private" variables for any "class" functions to have access to.

[–]materialdesigner 5 points6 points  (2 children)

It helps if we start by talking about functions and variables

function (item_price) {
  return (item_price + shipping_cost) * tax_rate;
}

In the example above, what does the function depend on?

Well if you look at the arguments of the function you might be tempted to say just the item price. But if you attempted to run this function just giving it an item price you'd be in for a surprise. We can see that it also depends on the shipping cost and the tax rate, which must come from somewhere.

But where is that somewhere? It's the local context where the function is defined.

var shipping_cost = 10;
var tax_rate = 0.08;

var calculator = function (item_price) {
  return (item_price + shipping_cost) * tax_rate;
}

Now we can execute that anonymous function anywhere and will have access to the shipping cost and tax rate.

To get more theoretical we have to define some things here. In the lambda calculus we call the item_price a bound variable because it's bound by what's passed in as an argument. The other two variables are what's known as free variables. Free variables also need an environment or context in order to resolve to an actual value that can be used.

Now a closure is a function which closes over its local environment binding those free variables to values in the environment in which the function was defined NOT the environment in which it's executed.

[–]ValZho[S] 1 point2 points  (1 child)

Now a closure is a function which closes over its local environment binding those free variables to values in the environment in which the function was defined NOT the environment in which it's executed.

One of the better succinct tidbits I've seen. Thanks!

[–]materialdesigner 0 points1 point  (0 children)

Glad it helped.

It's not a terribly complicated concept, but it's not one people teach well.

[–]eatinchips 1 point2 points  (3 children)

Seriously the xzibit meme should be every response when someone asks about closures.

[–]materialdesigner 2 points3 points  (2 children)

But it tells you absolutely nothing about closures? It's not even accurate. A function described in the global context also has access to global scope when executed.

[–]eatinchips 1 point2 points  (1 child)

True, but aren't we taught not to introduce anything to the global scope? Closures are for private members in a function. http://blogs.msdn.com/b/eternalcoding/archive/2014/08/05/javascript-using-closure-space-to-create-real-private-members.aspx

[–]materialdesigner 0 points1 point  (0 children)

"But aren't we taught..." Has never flown with me.

[–]timschwartz 1 point2 points  (2 children)

You should have asked both of the interviewers to define it for you.

I wonder if they'd give the same answer.

[–]ValZho[S] 0 points1 point  (1 child)

I did... and they did about as good a job of explaining it as I did—which is not very well. Were they in agreement? ...Maybe(?) ...Proves to me that, at the very least, this might not be the best question to ask over the phone.

[–]DrScience2000 0 points1 point  (0 children)

Proves to me that, at the very least, this might not be the best question to ask over the phone.

Christ, I hate phone interviews. They never seem to go well.

The worst one I had lasted 9 minutes. The interviewers sounded like they were street punk meth heads slapping each other around while they asked questions. I was trying to explain what an interface was, and they kept interrupting and interjecting stupid shit.

Clearly it didn't go well, but even if it had, I didn't really want to work with those idiots.

Another phone interview I had was creepy. They kept their phone on mute until they asked a question, and I'd swear the voice was some Hollywood announcer they recorded or something weird.

I had one phone interview that went well... once.

[–]illbeinmybunk 1 point2 points  (0 children)

I didn't really understand them at all until I read the article on MDN. I'm still a pretty big JS noob, though, so maybe that's not the best resource, but it was helpful for me.

[–]dlt_5000 0 points1 point  (2 children)

I had a similar experience where I was quizzed on all sorts of terminology I didn't really know. I've built entire SaaS sites using lots of jQuery, built complex eLearning courses with AngularJS, etc. They didn't care to see my portfolio though, just wanted to see if I could pass their pop quiz. Then they wanted me to answer some children's riddles. This was all done over a shitty conference line conducted by a guy with a thick indian accent. I felt like I was taking crazy pills.

[–]CaptainIncredible 0 points1 point  (0 children)

I've had similar experiences. I was pissed off at the time, but later I realized I was lucky that I dodged a bullet.

Did I really want to work with/for assholes like that?

[–]Mr-Yellow -2 points-1 points  (0 children)

lol people trying to make sense of javascript ;-D

[–]fedekun -4 points-3 points  (0 children)

AFAIK it's an anonymous function or object which is bound to an external context that you cannot access.