Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Understanding Closures in JavaScript!
You have completed Understanding Closures in JavaScript!
Preview
Closures can be found in all sorts of places in the wild. In this video we'll explore a few of those places, and show an example of a common problem that can be solved with closures.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
What are some real world problems
that are being solved by closures?
0:00
One use is to distribute
software packages.
0:04
Even simple projects can depend
on several different libraries.
0:07
Such as jQuery, Moment.js, or Underscore.
0:11
Each of these libraries use closures
to prevent variable conflicts.
0:15
If they didn't, a lot of bugs
would emerge.
0:19
There's a pattern called the module
pattern, which is employed for
0:23
distributing JavaScript code.
0:26
Check out the treehouse
content on the module pattern
0:29
linked in the teacher's notes.
0:32
In the Express J.S., framework for
0:34
note, some middlewares offer
configuration using closures.
0:37
If you haven't worked with express,
the way you configure it,
0:42
is bypassing in functions
called middleware.
0:46
The middleware should have a function
signature with three parameters,
0:49
with the request, response,
and next like so.
0:54
But there is for
example a middleware called Morgan.
0:58
That can be used to log
feedback from your app.
1:01
You include Morgan like this.
1:05
By calling it and passing it in a string
and optionally other arguments.
1:07
Here we're passing in the string of dev,
but what's going on here?
1:14
Where is the request, response and
next arguments that our middleware needs?
1:19
Let's take a look at the code.
1:24
Here, we see the Morgan function that
we can import into our Express apps.
1:27
It accepts Forma and Options.
1:32
Then it does some checking down here for
what's been passed in.
1:35
The Morgan function is the outer
function of our closure.
1:40
Down below,- its returning and
1:45
in a function with the correct method
signature to use as middleware.
1:50
This in a function has been configured,
1:57
based in what was passed
in to the outer function.
1:59
Middlewares will often use closures.
2:06
Allowing Middleware's behavior to be
configured by passing in arguments.
2:09
Finally, let's take a look at a common
gotcha, assigning functions in for loops.
2:16
If you want to follow along with me,
watch the workspace with this video or
2:21
download the project files.
2:26
In this project, we have two files.
2:28
An index.html page, which loads
a JavaScript file.
2:30
There are three buttons in the H.T.M.L.
file.
2:36
Switching over to the JavaScript file,
we see that we're getting the buttons.
2:41
And then, looping over them,
adding a click handler to each one.
2:47
Each of the button handlers will
log its name to the console.
2:53
Let's run this in the browser.
2:58
I'll open up the console, so
we can see the messages and let's test it.
3:02
I click on the first button and
third is logged.
3:08
Click in second, third is logged again.
3:12
When I click third,
it produces the correct result.
3:17
What went wrong?
3:21
Let's look at the code again.
3:22
A for loop pollutes the global scope,
when it's declaring variables.
3:25
Remember when we said that functions have
access to variables outside themselves?
3:32
In the case of each click
handler created in this loop,
3:40
it's accessing the same variables.
3:45
The button name from the global scope.
3:48
The value of button name
changes as the loop progresses.
3:51
From first to second and finally third.
3:54
When the loop completes,
4:02
each button handler is set up to
report the value of button name.
4:04
These three click handlers are closing
over the global value of button name.
4:09
When any of the event handlers
are triggered, they will log the current
4:17
value of the global variable.
4:22
in our case, it's third.
4:27
A solution to this problem is,
to supply a closure for each handler.
4:31
Instead of supplying an anonymous
function as the second parameter here.
4:37
We'll call a function that
will return a closure.
4:42
Above the for loop, let's declare
a function called create handler
4:46
Createhandler will
accept a name parameter.
4:56
And it would return a function.
5:02
The create handler will return.
5:07
Will have its own private
copy of the button name.
5:12
Finally, we just need to call this
function in place of the anonymous
5:19
function here.
5:23
The createHandler is invoked
with the button name
5:31
Every time it goes through the loop.
5:35
Encapsulating the button name as
a private variable in the closure.
5:39
Let's try this out in the browser.
5:45
It works.
5:53
Each button now,
is correctly referencing its own name.
5:54
I just want to mention that this
issue that we fixed with closures
6:00
has already been addressed
in ECMAscript 2015.
6:04
If we were to simply
put the keyword of let
6:08
Instead of var here where
we declare buttonName.
6:13
Each click handler would receive its own
copy of buttonName as the loop progressed.
6:17
That means we wouldn't need
to create any closures,
6:23
in other words the let keyword
creates a new block scope.
6:27
Or a scope for local variables,
through each iteration of the loop.
6:31
This wasn't supported before
EcmaScript 2015.
6:37
Until ECMAScript 2015 is supported
in all browsers,
6:40
You may find yourself needing to
know how to handle this use case.
6:46
For more information on the let
keyword see the teacher's notes.
6:50
There are many more places closures can
be useful, and we've only explored a few.
6:55
Now, we can recognize them
when you see them and
6:59
use them in some of your own creations.
7:02
Thanks for joining me and
I'll see you next time, happy coding.
7:05
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up