Skip to main content

almost 3 years ago Syntax Podcast

JavaScript Closures & Scope Explained

Wes Bos

Wes Bos Host

Scott Tolinski

Scott Tolinski Host

Topic 0 20:18

Closure for caching

Wes Bos

what the use case is for me to even use this type of thing. So One more example I have is if you want to create like a logger function like an object is not a scope. But if you have an if statement or if you have a function or you have a case switch or any of that, called And every single time

Wes Bos

show name, the syntax show number, the date, and any guests that we have.

Wes Bos

Promises in a single way, but it kind of still works the same way. I'll link up the

Scott Tolinski

Promises.

Scott Tolinski

I get closures. You know?

Scott Tolinski

In your development career, Yeah. Which is it's so funny because, again, it does seem like such a complex thing.

Scott Tolinski

But it it for some reason, I don't know what it is. It's one of those topics that just sparks a lot of confusion for some reason, and it I'm not immune to that as well. I until I, like, had to

Scott Tolinski

write these types of things, I I had no idea

Scott Tolinski

And even here, you might be listening to this and thinking, like, I don't have any use for this, and that's totally fine.

Scott Tolinski

And it's not that big of a deal.

Wes Bos

I have a couple more examples here. Asynchronous work is not as popular. It was very popular in the callback world we have this idea of a closure. So when you create a function, that function has scope.

Wes Bos

The fact after they've died.

Topic 1 00:00

Transcript

Announcer

soft skill, web development, the hastiest, the craziest, the tastiest TS Webb development

Wes Bos

that you might not totally understand.

Scott Tolinski

It sounds interesting. It sounds maybe perhaps confusing. So we're gonna be talking all about what closures are, how to reason about them and and what what exactly like, why are they something that people even talk about, or why are they interesting? My name is Scott Tolinski. I'm a developer from Denver, and with me as always is Wes Moss. What's up, Wes? Hey.

Wes Bos

I did it in my beginner JavaScript course.

Announcer

Monday. Mon Monday. Hey. Open wide dev fans. Get ready to stuff your face with JavaScript, CSS, node modules, barbecue tips, get workflow, breakdancing,

Scott Tolinski

it's it's not a ton of fun. So we're gonna try to make it fun.

Scott Tolinski

Perhaps we will bring in a sandwich metaphor. I don't think so. But, you know, who knows? for the entirety of the the browser scope anywhere in your application

Scott Tolinski

anywhere in your application.

Wes Bos

I've done it a couple times when when teaching and whatnot, and it's always one of those, like,

Scott Tolinski

You define a variable on the global scope. You can reference that variable

Scott Tolinski

like, macro to microscope that we have. So for instance, we have a global scope, and that is everything that you can access globally.

Announcer

treats coming in hot. Here is Wes, Barracuda,

Scott Tolinski

scope in scoping, which is, like, always one of those things that I I feel like Causes people's eyes to glaze over a bit when they're learning about scoping or,

Scott Tolinski

ghee. Welcome

Scott Tolinski

closures are one of those things in JavaScript that have kind of a weird name. If you're coming to JavaScript script or programming. You're new to this stuff. You see the word closure.

Scott Tolinski

to Syndax.

Wes Bos

Boss, and Scott and then inside of that function, you return another function it's going to reach into the closure expanding its scope per se Yep.

Wes Bos

Yeah. Explaining closures. And, like, I've I've done the, like, explained closures.

Scott Tolinski

And,

Scott Tolinski

On this Monday, hasty treat, we're gonna be talking about closures. Now,

Scott Tolinski

Yeah. And it doesn't help that it goes along with, in general,

Scott Tolinski

With Wes, you never know if the sandwich metaphor is coming. So let's talk about scope overall. 1st quickly, so the different types of,

Topic 2 02:33

Introduction to local scope

Scott Tolinski

it's coming up with a value because it's been defined somewhere else. So

Scott Tolinski

used ways in JavaScript to limit the scope in which we're currently working in instead of having this giant accepts some things.

Scott Tolinski

We

Scott Tolinski

typically,

Scott Tolinski

In the browser,

Scott Tolinski

global scope full of everything.

Scott Tolinski

have for a full archive of all of our shows,

Topic 3 21:59

Closure for reusable logger

Wes Bos

In its closure scope, and it can console log the show name and the show number and the guests and all of that data. And you don't have to, like, Carry around or reconstruct the entire logger every time. You can simply just say log page loaded, and then the console log will look like variables are determined To find exactly what it's looking for. So functions make Enclosing scope.

Wes Bos

from that you can return, like, a log function where you can just say log Peace.

Wes Bos

Loading And the way that JavaScript works is if you are trying to reference a variable So it's sometimes nice to just tuck away complexity into its own function and then return a new function They still have their own scope, and they still are It's literally looking are function scoped,

Scott Tolinski

Yeah. But why don't you just use a class for some of these things? Right?

Scott Tolinski

You can call at any time, and it still has access to that data. So another thing to note that I don't know if you you specifically mention because people might be listening to this and be wondering, like,

Wes Bos

law page loaded for episode 4 you do a little bit of math inside of there. You are dog years old. You create a variable of age, And then you inject it into the sentence. So you just you just made a variable quickly, threw it into a string, and now you're done with that. So the variables that were created inside of that function to do the work and then you return hello, s, or like, if you have 1 file and you want to be able to access it in another file without importing or exporting or passing or anything like that, you can stick it on Global This and you'll have it available to you. But Not too, too much. We have had this

Wes Bos

94 titled Blah Blah Blah with guests,

Scott Tolinski

And that's really, really one of the the pieces is that the closures are used less in object oriented programming, and they're more associated with, like,

Wes Bos

And any time we do anything, we load a page, we update something, we delete it.

Scott Tolinski

So if you're you're out there and you're using classes and stuff, you you might not run into this as much. Yeah. Because a class allows you just to stick that stuff

Scott Tolinski

functional programming topics.

Wes Bos

Scott and Wes.

Topic 4 06:06

let/const vs var for block scoping

Scott Tolinski

I posted a little little syntax for just a a JavaScript block. And and it's funny. I almost never use straight block syntax.

Wes Bos

open bracket, close curly bracket, and write some code in there, and it creates a block. Exactly. So we have global scope, we have local scope, and then you have this thing called enclosing scope,

Scott Tolinski

Do you ever use that where you're just using the curly brackets without anything else, like an issue? Or There are times

Scott Tolinski

to use This also says,

Scott Tolinski

Let or const over var nowadays

Wes Bos

And in dev tools, when you create a variable, you're creating a global variable. So if you wanna rerun that code, it says, ah, you already created that variable. Chrome DevTools will allow you to override it because it realizes you're doing, like, a iterative process, but not in Firefox. So if you just wrap a set of curly brackets around your code, And when you call that function, the initial data And then inside of that function, let's say you have a variable called name equals west, const name equals west.

Scott Tolinski

because it can be a little mysterious if you're assigning a variable inside

Wes Bos

get it, but it is a nice way to or if you have you should not do that.

Wes Bos

The only time I use that is in dev tools file, if it's not inside of a function or it's not inside of an if statement or anything like that, Check it out if you like this show. You can buy it. It's really good.

Scott Tolinski

if you know that, like, a block is containing

Scott Tolinski

to make its own scope. Yeah. And if you don't know what I'm talking about, you can just do

Scott Tolinski

the variable itself. So, things aren't meant to be put too much in the global scope. If you pollute the global scope too much, You're gonna have weird things where you're using a variable, and all of a sudden, a funk or having a function directly in the use enhance action. The use enhance action,

Scott Tolinski

of a block scope, and then you're accessing it outside of a block. And you're like, why did this? You know, why is this using the the value that it is? And it's more predictable

Topic 5 04:40

Local vs global scope

Wes Bos

go willy nilly making variables meaning that inside of that function,

Wes Bos

are creating their own scope, meaning variables created inside And the benefit of that is that it It's creating what's called the closure. Right? We'll we'll talk about in a second. We should talk real quickly is that JavaScript is lexically scoped. You may this is the an interview question. Right? Some programming languages are dynamically scoped, and most programming languages are lexically scoped, So the browser knows, okay.

Wes Bos

those curly brackets

Wes Bos

when you have little code fences. I like to think of the curly brackets. Fences. Oh. Code fences. Yeah. Curly brackets in JavaScript keep your variables in. That's what they're there for. Right? And every time you have a set of curly brackets, And the second, which is the name of the game, and it just says your hockey score is 1. Your hockey score is 2. Then you can go ahead and create another one. Create game soccer.

Wes Bos

outside of the gates of your curly brackets. Right? Now that we understand scope,

Wes Bos

except for an object, inside of a scope, JavaScript will first check

Wes Bos

functions, literally anything with curly brackets.

Wes Bos

So let's go with scope. Then we also have what's called local scope. So you've just created a scope. Right. And you can't access the variables inside of that because you've And inside of the create game, you create a score are not available if that is true, then it finds it.

Wes Bos

And that's really nice because you can

Wes Bos

is created

Wes Bos

Local scope is variables that are available inside of a block.

Wes Bos

So a block in JavaScript

Topic 6 13:11

Inner functions maintain outer scopes

Wes Bos

So really. So you you can't, hockey. So you're passing in is closed and the variables with the new data.

Wes Bos

of another function, let's call that an inner function, can still access the outer variable.

Wes Bos

If you put a function inside past Those 2 things have nothing to do with each other unless you explicitly pass the value into it and and introduce that value into the scope.

Wes Bos

So that inner function

Wes Bos

the very once the function is done running, the variables are garbage collected. But what happens if the inner function they're not going to leak out and just have some random thing. Var variables Create.

Wes Bos

If you talk about generating You can use a factory function and you say create logger, pass it the whole show, or or a for statement inner function unless you explicitly import and export them. And that is a super handy Right? And you can just store it in there. And with the function, you can't just stick the stuff anywhere. So you have to sort of create this idea of closure. So, yeah, you're right.

Wes Bos

where the variable is inaccessible to you because the function is done, But that internal you you say, like, const my name equals wes, and then you run the function called but its own scope

Wes Bos

being run. It's closed. But You've created a closure,

Wes Bos

What happens to that variable? I just said on the list for probably a couple of months now That is is not run yet, but it's just you've created a you dynamically created a function says, okay. Here it is. You can go ahead and call this later.

Wes Bos

that that inner function being able to access a variable

Wes Bos

And you've sort of created this little if you're doing As if you were doing functional work. Word. Alright.

Wes Bos

a function

Wes Bos

that's a basic function being to make global variables these days. It used to be you had a script tag, and you load in the script tag. Any variable that you declared inside of that JavaScript or

Topic 7 16:06

Dynamic scoping is uncommon in modern languages

Wes Bos

course notes for free on my website, is private variables. So you have a function called create game, It takes in a game name, so tricky things to to sort of do because

Wes Bos

That is set to 0. And every single time that you run that return function, where into its parent function where the code was written, the scope is determined by where the variables are written in your code, not where it's run, and that's most I would say most programming language. I wonder what languages are dynamically scoped. Oh, I'll I'll look that up while you take the next set section. So closures.

Wes Bos

and then you return a function called win.

Wes Bos

You call that win function. It will increment

Wes Bos

So let's talk about some examples of where a closure might be handy. All right. So one example is and I'll link up the actual code for this from my website, as I have all my beginner JavaScript

Wes Bos

variable that's called let score equals 0,

Wes Bos

basketball. Right? not where the variable was defined. So if you have a function that internally that you can still access and reference and update and return

Wes Bos

and you're creating a score variable

Topic 8 17:55

Closure example with Svelte

Scott Tolinski

the

Scott Tolinski

the function for me with the properties and the variables and the scope that I needed each time

Wes Bos

aren't a function per se.

Scott Tolinski

forms inside of SvelteKit

Wes Bos

when the thing is loaded, but What is returned does not. It doesn't run the function immediately. It returns you a new function that is sort of preloaded or bound So you have a function called say hello.

Wes Bos

Another example of closures is I think this is probably the most common one is modules. Modules and then Because I want to re rerun the same code over and over again.

Scott Tolinski

pass in your own variables to this thing. You couldn't have your own,

Scott Tolinski

having

Scott Tolinski

is by

Wes Bos

you. You have to pass

Scott Tolinski

essentially your own function each time this was going to be run, so I created a factory function that created

Scott Tolinski

enhanced

Scott Tolinski

So anytime my enhancing to be run, it wouldn't just call a function. It would create the function

Topic 9 14:35

Closures allow inner functions to access outer scopes

Scott Tolinski

Offer the ability to do dynamic or lexical scoping.

Scott Tolinski

but it does seem like several languages

Scott Tolinski

It says early versions of lisp,

Scott Tolinski

Some versions of Pearl have a keyword for dynamically scoped with the local keyword.

Scott Tolinski

hex. So almost nothing. TCL. Yeah. Almost nothing. Languages that you have not heard of or almost always, like, older kind of programming concepts or languages.

Scott Tolinski

bash and other shell scripts. But when I dug into it, I did find a Stack Overflow post where somebody says there's no

Scott Tolinski

not super common as a main feature in modern languages, when you will have this moment, and you're like, it all makes sense now. I understand,

Scott Tolinski

four

Scott Tolinski

Emax lisp.

Wes Bos

lives that are gone, what was it,

Wes Bos

the value from there. So that is what is referred to as a closure because the outer function has been closed over, and then run that function. That that was a really good example because let me reach outside of my scope and see, does this exist in the module scope, right? So you're essentially creating a

Scott Tolinski

there is no dynamic nor static scope in bash. So I it it's I you know, it's it's not, like, super crystal clear. It's Mhmm. Noble

Wes Bos

on in memory. It's not going to be garbage collected because something is still referencing those variables internally.

Wes Bos

neat little nesting spot for variables

Topic 10 12:03

Function scope creates closure

Wes Bos

And inside of that function, you say const sentence equals hello, Wes, 20 minute radius would be. Like, it just keeps going up a level, display name.

Wes Bos

So I'm just going to throw it out because there's no sense in keeping it around because eventually we're going to run out of memory on the user's computer. Right? That's what garbage collection is.

Wes Bos

variables inside of that function are created.

Wes Bos

They're garbage collected.

Wes Bos

When the function is done running, that function

Topic 11 19:15

Modules use closure

Wes Bos

in Node. Js or anything like that, of curly brackets and say, hey. I'm looking for a name variable. Is there any variable because that towards this variable.

Wes Bos

and whether that is a counter for how many times a function has run which is So lexically scoped means the score variable over and over again. So what you can do is you say like const hockey game equals create game

Wes Bos

is is maintaining state from the last time that it ran, and it says, alright. Well, if I already generated this image, and see what that actual value is.

Wes Bos

if you create a variable that is outside of your route handler

Wes Bos

Or my case, I often will create a cache and they are garbage collected, meaning that the browser put them into memory real quick, instead of, like, let's say if I wanted to console log the syntax passed around and maintained

Wes Bos

into the module scope, which I can't throw those out just yet because something is still pointing towards them. So dynamic scoping is really like a route handler what closures are. Essentially, they are just scope

Topic 12 03:00

Global scope in JS

Wes Bos

So if you want to stick something on Global Scope for whatever reason, Then you've just created a global variable. And that's why you

Wes Bos

there is a variable called global this. It's even available in the browser.

Wes Bos

global this, like sort of a closure in themselves.

Wes Bos

can type a variable in a script tag and then go into your dev tools and type it in in the console for 2 things, the score, which you can then update. It's a private variable.

Scott Tolinski

without having to even import or reference anything. It's just available to you. That's on the global scope.

Wes Bos

other platform, It's it's actually really hard you've now created 2 scopes. Right? You have your function scope, and then you have your if statement scope.

Scott Tolinski

you have like, the window is a global scope. Right? You can access things For the window, Yeah. And this is one of the reasons why people often say

Wes Bos

you can use the variable The handler will reach outside of the function scope disappear.

Wes Bos

In other platforms,

Wes Bos

So it's pretty tricky to actually do that anymore because did the work and then it closes. Alright. Well, like, literally nothing else is still pointing and of those a parent function

Wes Bos

camel case, and that will give you access in Node. Js. That will give you

Topic 13 07:31

Block scope syntax

Scott Tolinski

within your household. Is there any cheese within your household? And then maybe the next scope out would be, is there any cheese in my 20 minute radius?

Wes Bos

an immediately invoked function expression, b, You gotta have, like, real world examples of, like, when you might use that. Otherwise, it's just a, like, bizarre concept which is basically just a function that immediately you put parentheses on the end and it calls itself.

Wes Bos

say hello.

Scott Tolinski

you could think, like, 1 scope could be the bread. You'd say, is there any cheese in here, and it's checking between the 2 pieces of bread first. Yeah. Well, there's no cheese in here.

Wes Bos

by where the code is defined, not where it's run, meaning that we go through the whole example of just going up the scope chain.

Wes Bos

if you have curly brackets. Let and cons variables

Wes Bos

import or an export or you load something in via type of module, it's a, it's scarier. It sounds scarier than it actually is. And even though modules when you have multiple scopes nested inside of each other. So That's the reference it uses, but it will keep going up scope levels until it finds what it's looking for. And eventually you're going to hit global scope. And if it's not there, then

Wes Bos

If so, that's the one I want. If not, it says, alright, folks.

Wes Bos

side of this if statement or inside of this for loop or inside of this scope named name?

Wes Bos

the local gates tricky bits closures from my website. You can read through it. Just get a couple more examples in there to totally understand it. But hopefully that gives you a good example of

Scott Tolinski

Goes kinda up the tree, every set of curly brackets. So if we wanted to to bring in the sandwich metaphor here, the the one that I did for the Svelte site is for a Svelte action. The way that you can do, Head on over to syntax.fm enhance was run.

Wes Bos

If you have an if statement can still go up the scope chain like we were talking about earlier. Right? So little closure there where you put the cache outside of the handler and you can reuse it from function call to function call.

Wes Bos

Probably the most popular scope that you're not used to is module scope. So every single time is still referencing a variable from the outer function, a variable

Scott Tolinski

And then maybe the next scope out would be, However, I I found that you couldn't necessarily

Wes Bos

will not leak outside.

Wes Bos

I didn't find what I wanted. I'm gonna go one level up. So that goes one level up to the function scope and says, hey, any variables here named name? And inside of a loop or anything like that. And you know that there is no code before or after it that you are going to be accidentally overwriting feature of modules because you're not accidentally creating all this Global scope. You don't have to. In the past, we used to have create what's called an IFFI, We are mostly all using modules. Module we'll talk about that in just a second, but modules have their own scope. In Node. Js land, There is in pretty much every and let and const are block scope, meaning that if statements, for loops, a module, meaning that variables created inside of that module page. And then

Wes Bos

you have a hockey, soccer,

Wes Bos

is

Wes Bos

JavaScript file itself where a function could run, but you have to wait a number second. It's it's not as popular anymore now that we have that variable exists nowhere. So the scope lookup So if you have like a serverless function

Topic 14 23:20

Closures used more in functional programming

Scott Tolinski

And don't forget to subscribe in your podcast player or drop a review if you like this show.

Wes Bos

on the class itself.

Wes Bos

on class methods, but not nearly as much and that is what is referred to as a closure, meaning that You've created this ominous space you're kind of pooched because accesses something called name,

Wes Bos

That is a very good use case. You still will run into closure use cases that runs immediately, for saving data in my OG images I talked about earlier.

Topic 15 17:13

Closure for private variables

Wes Bos

a function that is sort of preset with a bunch of data. And even Scott made a generator function in the

Wes Bos

They're often called factory functions, from the outer function, function has been passed the show earlier, it has access to the entire show

Wes Bos

You can say soccer win, right? And it will say your soccer score is 1. Your soccer score is 2. So that is a nice way to sort of like where you are you can return it to call it later. Right? So you can have

Topic 16 11:01

Lexical vs dynamic scoping

Wes Bos

Right above that function, They're not available to other files that can be the sorry. Factory function. Do you wanna explain the one that you didn't in our our Svelte site? Yeah. Well so That's it for today. Hopefully, you enjoyed that. We will catch you later.

Share

Empowering developers for over 286196382558 milliseconds!