I’m launching the series with the $40k question. If you answer this question wrong, there’s a good chance you won’t get hired. If you do get hired, there’s a good chance you’ll be hired as a junior developer, regardless of how long you’ve been working as a software developer. On average, junior developers get paid $40k/year less USD than more experienced software engineers.
Closures are important because they control what is and isn’t in scope in a particular function, along with which variables are shared between sibling functions in the same containing scope. Understanding how variables and functions relate to each other is critical to understanding what’s going on in your code, in both functional and object oriented programming styles.
You’ll also be vulnerable to misunderstandings when you’re trying to understand what somebody else wrote.
Not only should you know what a closure is, you should know why it matters, and be able to easily answer several possible use-cases for closures.
If you can’t answer this question, it could cost you the job, or ~$40k/year.
Be prepared for a quick follow-up: “Can you name two common uses for closures?”
What is a Closure?
To use a closure, define a function inside another function and expose it. To expose a function, return it or pass it to another function.
The inner function will have access to the variables in the outer function scope, even after the outer function has returned.
Using Closures (Examples)
Among other things, closures are commonly used to give objects data privacy. Data privacy is an essential property that helps us program to an interface, not an implementation. This is an important concept that helps us build more robust software because implementation details are more likely to change in breaking ways than interface contracts.
“Program to an interface, not an implementation.”
Design Patterns: Elements of Reusable Object Oriented Software
In the example above, the `.get()` method is defined inside the scope of `getSecret()`, which gives it access to any variables from `getSecret()`, and makes it a privileged method. In this case, the parameter, `secret`.
Objects are not the only way to produce data privacy. Closures can also be used to create stateful functions whose return values may be influenced by their internal state, e.g.:
const secret = msg => () => msg;
In functional programming, closures are frequently used for partial application & currying. This requires some definitions:
Application: The process of applying a function to its arguments in order to produce a return value.
Partial Application: The process of applying a function to some of its arguments. The partially applied function gets returned for later use. Partial application fixes (partially applies the function to) one or more arguments inside the returned function, and the returned function takes the remaining parameters as arguments in order to complete the function application.
Partial application takes advantage of closure scope in order to fix parameters. You can write a generic function that will partially apply arguments to the target function. It will have the following signature:
partialApply(targetFunction: Function, ...fixedArgs: Any) =>
If you need help reading the signature above, check out Rtype: Reading Function Signatures.
It will take a function that takes any number of arguments, followed by arguments we want to partially apply to the function, and returns a function that will take the remaining arguments.
An example will help. Say you have a function that adds two numbers:
const add = (a, b) => a + b;
Now you want a function that adds 10 to any number. We’ll call it `add10()`. The result of `add10(5)` should be `15`. Our `partialApply()` function can make that happen:
const add10 = partialApply(add, 10);
In this example, the argument, `10` becomes a fixed parameter remembered inside the `add10()` closure scope.
Let’s look at a possible `partialApply()` implementation:
As you can see, it simply returns a function which retains access to the `fixedArgs` arguments that were passed into the `partialApply()` function.
This post has a companion video post and practice assignments for members of EricElliottJS.com. If you’re already a member, sign in and practice now.
If you’re not a member, sign up today.
Explore the Series
- What is a Closure?
- What is the Difference Between Class and Prototypal Inheritance?
- What is a Pure Function?
- What is Function Composition?
- What is Functional Programming?
- What is a Promise?
- Soft Skills
July 2019 — Clarified intro to explain why answering this question wrong could cost you a job or a lot of money in salary.
Eric Elliott is a tech product and platform advisor, author of “Composing Software”, cofounder of EricElliottJS.com and DevAnywhere.io, and dev team mentor. He has contributed to software experiences for Adobe Systems, Zumba Fitness, The Wall Street Journal, ESPN, BBC, and top recording artists including Usher, Frank Ocean, Metallica, and many more.
He enjoys a remote lifestyle with the most beautiful woman in the world.