Lesson Description

The "Closures" Lesson is part of the full, Getting Started with JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle introduces the concept of closures in JavaScript, explaining how they work by demonstrating examples of functions accessing variables outside their scope. He discusses the idea of closures keeping track of dynamic variables and accessing outer scope variables, emphasizing how closures allow functions to remember values even after the outer function has finished executing. Kyle then walks through a practical example of nested functions, showcasing how inner functions retain access to variables from their outer scope, ultimately highlighting closures as a fundamental aspect of how functions interact with scope in JavaScript.

Preview

Transcript from the "Closures" Lesson

[00:00:00]
>> WebDevSimplified: Moving on, I now want to talk about again another really confusing topic inside of JavaScript, which is closures. And luckily, while this is a tricky topic, we've actually already dealt with and seen how closures work inside this project. So understanding them, the naming is a little bit confusing and they like to ask you tricky questions in interviews about this, but really it's a concept we've already covered pretty in depth.

[00:00:20]
So closure is just what happens when you have an inner function that accesses variables in a scope outside of it. So here is pretty much a really simple example of a closure. We have a print function which uses a variable A which is defined inside of this global scope. So we're able to access scope variable outside of the current function inside of a function. That is the shortest example possible, a closure.

[00:00:43]
Now, most often when you hear closures referred to, they aren't quite this simple, but the idea of accessing variables in a scope outside your current scope as a function, that's really what a closure is. Now you can even use closures with dynamic variables, and that's what makes them really interesting. For example, we have a variable A here which is equal to one. We use that inside of our print function and then we're able to redefine that variable.

[00:01:05]
So let's copy over this code to see exactly what's going on because this is actually where the confusion starts to come in. We define a variable A here. We define our function here, we change the value of our variable here, and then we call print at the very bottom. If you're just reading through this code top to bottom, you're thinking, OK, A equals 1. So when I log out A, it'll be equal to 1. But since JavaScript doesn't quite work that way, I mean, technically we're hoisting this to the very top of our file anyway, what really these closures care about is when you have dynamic variables, it just uses whatever the most up-to-date value of that variable is at the time you call that function.

[00:01:38]
So here we update our value of A to 2 before we actually call print. So it's going to use that most up-to-date value of 2 when it tries to log out whatever the value is inside this print function. And that's kind of the magic behind closures is it's able to keep track of these variables outside the current scope and use whatever that latest value is directly inside of it. So if I were to come down here and I would just say A equals 3 and then I call print again, you can now see it logs out to the first time because that's the most up-to-date value at the time in our code.

[00:02:07]
We then update to 3. Now the next time I log, it'll be printed out 3 because that's the new most up-to-date value for that a variable. Now the example most people think of when they think of closures is having one function inside of another function and accessing scope from that outer function. This is the textbook example of an interview question that you're going to get asked on closures. It's going to ask you how does this particular thing work and what all the variables mean.

[00:02:30]
So here we have a function called Outer and inside that function we have another function called inner. So we're defining a function inside of another function. We haven't really seen this up until this point, but this is something that's perfectly valid that you can do in JavaScript, and it doesn't matter if I define this as a normal function or as an arrow function or anything like that. I just have a function inside of another function which is perfectly valid JavaScript.

[00:02:51]
And the idea behind closures is this inner function still has access to all the variables in its outer scope. So it has access to the A variable, which I passed into outer, and if I had any global scope inside of here, it would also have access to that as well. So let's take a look at actually playing around with this code because that's probably the easiest way to really understand exactly what's going on.

[00:03:10]
So again, I have this outer function. Inside of it it has the inner function, and then I'm returning that inner function. So this already can be a little confusing because I'm calling a function and instead of giving me a value like 123, it's returning to me a brand new function that I can also use. So if we look at how we use this code, we are calling that outer function, which again returns to us a brand new function which we call new funk, and now we can take that new function that's returned to us and call that function with a particular value as well.

[00:03:38]
So that alone is already somewhat confusing, especially when you're getting started, is realizing that functions don't just have to return values like 1, 2, or 3. They can also return other functions or anything else that they want to. The other thing to understand specifically when it comes to closures is that when we call outer we pass it in a value of one. That means this a variable up here is set to the value of 1, and our inner function remembers that.

[00:04:01]
It says, I know what that value is. That value is one. So anytime we use a inside of here, it's going to print out the value of 1. Now when we call this inner function down here when we call new funk, we pass in a value of 2 for B. So now my inner function is able to say, OK, I remember the value of A. That was 1 when this function was called, and I'm getting this new value of B being passed in, which is 2.

[00:04:23]
So when we log out our values, it's printing out 1 followed by the value of 2. And this is the textbook example of closures. If I create a function inside of another function, it remembers what the values of all the stuff in the outer function are, so it's able to keep track of this value is 1, while this B value is 2. Now I know this is confusing, so if there's any questions, please ask them. I'll try to explain it the best that I can.

[00:04:48]
I just ask like why does it work that way? Is this like a memory situation or like how is it? Yeah, I know how to do that. So I don't know the exact inner workings of like how the JavaScript engine parses everything to make it work properly, but the reason that they implemented it to work this way is because otherwise functions would be much less useful if they could never access the scope outside them, because kind of a little bit more of like a technical deep dive here is when we call this outer function, you can see our code runs and as soon as we return, remember how I said that ends everything inside the function.

[00:05:17]
Normally in a lot of other programming languages that means that this a variable would be completely forgotten about. But JavaScript implemented this into the language that this a variable should be remembered because it's actually being used by this inside function. So closures are essentially a way for these functions to remember variables from outside of them, even when they're no longer used, for example, in this outer function anymore.

[00:05:40]
It keeps track of them inside of its own function use case. So it's really just there as a way to make all of this nesting of functions work properly, because a lot of other languages don't allow you to do this type of thing. Yes. And this topic in particular is covered in very deep detail in JavaScript: The Hard Parts by Will Sentence, as well as Kyle Simpson's deep JavaScript foundations. Yes, I'd highly recommend checking those out if you do, because I mean you can spend a half hour talking just about closures, especially if you want to get into the nitty gritty details of like the technical implementations like you're talking about.

[00:06:15]
That's probably the best place to go for that. Another thing is we obviously can access multiple scope layers. We talked about, you know, just a function accessing its outer scope, but you can go as many levels nested as you want. For example, here we have a global variable, we have this outer scope variable, and this inner scope variable, and we have access to all three because again we're always looking outward.

[00:06:33]
And the thing to understand about closures is don't think about them as a new concept. Just think about them as how scope works for functions, because we've already talked about scope and the fact you can always look outward. That's just what a closure is. It's just a function that looks outward to see other scope inside of it. A lot of people get really worked up when they hear the word closure thinking it's this brand new big thing, but it's just scope working for functions like they normally would for every single thing else inside of JavaScript.

[00:06:57]
Again, just like scope, it's one way access. You can only ever access the stuff outside of you and you can't see the stuff that's directly inside of you. Now, kind of an example of what an interview question would look like is they would give you this particular code and they would ask you, hey, what does this print when I call this code down here? So you would need to understand how closures work like we've talked about where this inner function keeps track of what this outer functions variable is, so it knows that we passed in 5 here and we passed in 3 to this inner function, so we know that this will return 8 to us when we actually run.

[00:07:26]
This is a super common junior developer question that you'll get asked a lot of interviews. So understanding this closure topic and that it's pretty much just a fancy way of scope working is really important to understand. I want to give you this quick practice exercise that you can work on. I want you to create a function called Create greeter that takes in a greeting parameter. This can be anything like hello, hi, what's up, it doesn't matter, and it's going to return to you a brand new function that takes that parameter, which we call name.

[00:07:52]
And it's going to then return to a function that logs the greeting plus the name. So this new function takes a parameter called name and prints out whatever that outer parameter's greeting is, plus that name added onto it. So hopefully you guys had some time to actually go through and solve this particular problem. Now we just want to go through the solution real quick. So if we take a look here, we have that function Create greeter, which takes in that greeting parameter, and here we're returning a function.

[00:08:19]
Now this is a little bit differently formatted code than some of the other stuff I've shown you because I'm just returning this function in line as an anonymous function. It doesn't matter if you write out the code like we showed up here with creating a function and returning it later, or if you want to return it in line as an arrow function, they're both going to work exactly the same. But you can see this brand new function that we're creating, it takes in a name property and it's combining together our greeting and our name.

[00:08:43]
So now we can use this to create different greeters that have different names. For example, we can have one that starts things with hello and another one that starts things with hi and depending on which one we call, we get different greetings at the start. So if I call Say hello with Kyle, it prints out hello Kyle. Well, if I say say hi with Sarah, it'll print out hi Sarah. So this allows us to kind of create different things for different purposes based on returning a function from another one.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now