Practical Uses for Closures
The closure is a powerful tool in JavaScript. It is commonly used in functional programming languages, but often misunderstood. Like other JavaScript fundamentals, understanding closures is necessary to write expressive, concise and maintainable scripts.
What is a closure?
At first glance, a closure is simply a function defined within another function. However, the power of closures is derived from the fact that the inner function remembers the environment in which it was created. In other words, the inner function has access to the outer function’s variables and parameters.
What’s it look like?
Below is an example of a closure (courtesy of Mozilla):
1 2 3 4 5 6 7 8 |
|
Our outer function — pam
— does three things:
- Define a local variable,
name
- Define a function,
displayName
- Call
displayName
displayName
doesn’t define any local variables, yet it is able to alert name
because name
has been defined in the scope in which the closure was created — that of its outer function.
Closures can do more than just read their outer functions’ local variables — they can overwrite them, too. Observe below:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
As we can see, closures are capable of not only reading, but also manipulating the variables of their outer functions.
Function factories
One powerful use of closures is to use the outer function as a factory for creating functions that are somehow related.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Using closures as function factories is a great way to keep your JavaScript DRY. Five powerful lines of code allow us to create any number of functions with similar, yet unique purposes.
Namespacing private functions
Many object-oriented languages provide the ability to declare methods as either public or private. JavaScript doesn’t have this functionality built in, but it does allow to emulate this functionality through the use of closures, which is known as the module pattern.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Using closures to namespace private functions keeps more general namespaces clean, preventing naming collisions. Neither the salary
variable nor the changeBy
function are available outside of dwightSalary
. However, raise
, lower
and currentAmount
all have access to them and can be called on dwightSalary
.
These are a few popular uses for closures. You’ll surely encounter closures used for other purposes, but these are a couple simple ways to incorporate closures into your code in an immediately useful way.