in this video
I'm going to tackle a very confusing but fundamental and important topic in Javascript programming something called a closure
It's a big topic, and I think [I] probably could do several different videos around it
I could also probably slow into it a bit more but in this video
I'm just going to look at it in the context of set interval
And kind of unpack everything [that] has to do with [the] closure with this particular example
and then
Things will be confusing and you'll feel a little weirded out
And I'll come back and make some more videos based on questions people [asked] with some other scenarios that will hopefully make this more clear
But let's just give it a try. I think give it a try
You can give it a try by watching and I think it's going to be ok so, what is the scenario here?
The scenario here is that I have and the canvas is irrelevant
It's just sort of there to show that I could also have a canvas
Animating the thing that's important here are these two particular Dom elements?
One of which you can see is
Counting up a number every 500 milliseconds you could think of any other types of thing you might do with a dom element
[that's] doing some type of animation and the second one is not animating at all
So, how is the first one animating now first of all again?
I'm using set interval in a separate video that. I will reference at some point. I'm going to look at why you might use requestanimationframe
[instead] of set interval, but for simplicity I'm using set interval right here
So what set interval does is it says call this function time it right here every 500 milliseconds
so every 500 milliseconds increment a counter and update the htML content of that element by that amount [so]
What if I want to do the same thing for the second Dom element well certainly I could just add
Timer to HtML. You know counter and we would see here
That both of them are lockstep and in sync
But there's only one function being triggered what if I want each [one] of them and have their own?
Interval so they each get their own counter or they each get their own
Time that [they] wait to increment that counter you might think of it. Here's a nice way [of] thinking about this
What if you had an object?
Right even if you like program to Java or C++
And even Javascript you had an object each one of these things was an object and it had
properties associated with it it had a counter and
had an amount of time it waits to increment the counter a closure in Javascript is actually a way of doing something very similar to
object-Oriented programming where I want to
bottle up
I wanted to create this little
Container this bubble is close your bubble that has all the stuff that has to do with each one of those dom
Elements
and how do I create that bubble so let's come over here for a second and
Let's just say and I feel like I'm in the darkness today for some reason
But I don't know why this seems darker than usual, but it is what it is
You can hopefully see me and read this um so let's just think about functions in Javascript for a second
function
Rainbow
Right you have [setup] and Drawn P5, and there's all sorts of window although. There's all sort of functions
You can write and define in Javascript all the time, and I could have another function down here. [I] could call it on what's up
unicorn
For lack of a better thing to think of and now I have two functions each one of them [Define] separately outside
[of] each other and
incidentally if this is no different in
Javascript and now I am really easing my way into this but to say var rainbow
equals function
Right [a] function is just a thing you store in a variable
[this] function is stored in the variable rainbow this function is stored in the variable Rainbow and in Javascript, then it's totally reasonable
That you might
Define a function inside
another one
So this unicorn function could be defined
right inside of here
This means unicorn is a local variable to the rainbow function. So if I were to call unicorn here
That would be totally reasonable that would work if I were to call unicorn down here. I
Could not call unicorn down here because it's out of scope because unicorn is now only local to rainbow now
What if I?
had a variable here like
What goes with?
Pot of gold. I don't know
What goes with Rainbows got stars I?
Have a [Star's]
variable which equals
15 oh boy, why don't you choose a counter this I like so like lost in my world of rainbows
Which is just ridiculous at this point [and] kind of embarrassing so what if I have a counter variable in here?
This is also a local variable to the rainbow function
Now let's think about this when I call the rainbow function
that means these codes should be executing which means somewhere in the computer's memory a
Counter is made and stored. What if I call the rainbow function again?
Well if I call it again a new counter is made
These local variables inside of a function are things that are
Generated again and again every time you call the function that should almost be in a way intuitive or not
It's basically you haven't thought of before
But this is something you've definitely used before the same is true of this function each time I call Rainbow a new
Function unicorn is declared and defined
Which in some cases might be very inefficient? [which] is why sometimes?
I don't want to like read [eclair] that function all the time if rainbow is happening over and over again
[I] wanted to have it outside
Just use it in there, but what if you wanted this function to operate differently each time you called rainbow [well], this is precisely
so this by the way is a closure a
closure is a
function being enclosed in another function and and this idea of all of this stuff being
maintained all this data the variable this function and including arguments that might be passed in here as
Each time you call the rainbow function this bubble is made which a counter is stored and [a] reference to this unicorn function is stored
Now there's all sorts of weirdness and strange things you can do with this newfound
Power of putting a function inside a function, and I would love to get to all of these scenarios in all of my videos
But let's come back to here
This is precisely what I want in this particular scenario right because what I want are [two]
Counters, so if I say I'm going to I'm going to I'm going to just make up a function for a second make
Animation I
Don't know if that's [oh] make make make timer make timer animation all it right, and then I'm going to define [that] function
make timer
whoops I'm defining it and I say var counter equals zero, so
[what] I want to do is each [time] I make the timer I get a new counter so I could certainly call make timer twice
So that makes a counter variable twice
Local only to this make timer function, but that's going to be fine. Why?
Because here set interval is
Going to be called inside the make timer function
And if set interval is called inside the make timer counter is no longer a global variable
Then I could define here's a nice little closure for you. This time it function can be defined in here take out this one
Look, what's happening here each time each
So each time I call make timer I create a counter
I set the interval and this function makes use of that particular counter
So one thing that's really important about thinking about scope [and] Javascript. Well. I love stuff
It's kind of like weird to think about but it's really interesting is that the scope isn't?
Just where your variables are declared but kind of like when things happen like this function is all set and [done]
But this set interval means time it is going to happen later and later and [later]
So the closure even though this function is executed and finished all of the things made in here all the stuff stored in Memory is
Maintained it's maintained as long as something still needs it and time it still needs it because set interval
[we'll] be calling it again and again
So let's just look at this and I'm going to call it just once so this should work for just timer 1
Let's look at this you can see timer 1 is now counting up, right?
That's it's doing exactly [what] we want it to do
Why is it doing that because we create a counter we call set interval and every 500
milliseconds the counter is incremented and the Dom element is updated, but now I
Have this function make timer. It's only working for timer one because timer 1 is hard-coded inside there. So why not?
Just say I'm going to just give it an argument call it elt
Generic Elements, so now I want to make a timer for timer one
same exact result
But now this is the magic the magic of the closure I can make the timer
For timer - so this whole bubble this closure bubble was almost like this object this counter this time it function to set interval each
One of these will be done again each time [I] call that function for timer 1 and timer to the closure being this function in
Close even though this function is happening later and later and later in life
In a lot of programs running that all the stuff around it is maintained in memory for it
So now if we run this we can see
both of them
What so what happened? I made a fatal flaw here
I still hard-coded in timer 1 so I have to change that obviously the elt the point is to take the Dom element
That's passed in and then use update that one's particular
And you can see now here
They owe their both going why they're both going exactly at
500 milliseconds each so what if I add another argument here 500 and you know and this one will be at
312 so totally arbitrary and I add an argument here called wait and
Now I add wait there. So now when I call make timer, and I forgot a parenthesis here what I'm doing is saying
Make this closure create a counter
Start a set interval process with a particular function and remember that function this function
If I were to put this right, not as a closure
But out here
It wouldn't make any sense because elt and counter don't have any scope out here in the global scope
So I need that function to be read eclair each time
inside of make timer and
Here we go. Let's make this happen, [okay]?
[look] at this and you can see now each one individually is just operating on its own
Time because they both been triggered with one with 500 milliseconds and one with 312 and this is a closure
So I could add a third Dom element and a fourth one
I could do this in a loop or I could have them all animate I could start and stop them I could store a reference
To the interval of different buttons when I click on it it starts when I click off [of] it it stops
So there's a lot of possibilities here
What I might suggest to you is think about you know try to use this exact framework and think about like well
What's something more interesting you could do in terms of color or something else besides just counting numbers?
The other thing that I might consider is what happens if you put those dom elements into an array?
can you loop through them and
Execute a closure for all of them to have them all doing some type of animation um that sort of thing [so] [I]?
Hope this helps you get started with this idea of understanding what a [Javascript] closure is and what it's for
I think [this] will come up again and again in videos that I make it certainly comes up a lot when making multiple api queries
It comes up. I think [an] example that I want to make [that] looks up playing a musical melody
It can come up if I have an array of notes, and I want them to each to happen a certain period of time
So I look forward to your questions
And see if I can come back and make [some] more videos to clear up anything or to cover this more again
So thanks for watching [I]
Can't believe I just made a video about a closure
Which is something that [I've] ever even heard of like less than a year ago
I probably heard of it, but was like. I don't know what that is so hopefully this made sense
It was correct, [so] the internet will correct me. I'm sure if I was wrong, and I will see you all [sometime] soon
Good. Oh, and this is only 12 minutes. I think that's kind of amazing