Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
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