Closure in JavaScript
Mastering JavaScript Series
In programing languages, a closure, is a way of name binding. Name binding is simply binding some code or data with identifiers.
JavaScript functions are first-class objects. Meaning they contain more than just the code that the programer types. Among the extra stuff, it contains a closure. It is a record that stores variables available in a function’s environment at the time they are defined. This way, we don’t have to worry about the function breaking down on us when we call it later in the code. This binding mechanism allows the function to operate just fine no matter how many times you call it or when you call it, essentially making the function a standalone, robust, and reusable piece of a program. Lets look at the following example:
In the example above we have a function named outie
that has one variable inside and returns a function named innie
. This innie
function in turn has a job of its own, which is to return outiesVar
every time innie
is run.
Pick a sheet of JavaScript code, you can read it line by line until you get to a point where a function is recalled. You may stop there and go all the way up to where the function is defined and read what that function does and resume your reading afterward.
JavaScript achieves this task similarly by binding the function to the data it needs to run. This way, every time the function is called it has the necessary data to perform its duty.
Every time you run JavaScript code, it runs inside a default global execution context. Context is important, much like natural language, context helps us understand what our syntax can actually achieve.
Beside the global execution context, our code has the ability to create several local execution contexts. Each having their own scope. Most of the time these scopes are generated and determined by functions. In the code above when our outie function returns innie
function, you can see that innie
comes with some extra stuff. Among them is an array of scopes. In that array you have a record called Closure that binds the innie
function to the outiesVar
. With this feature, innie
can always be called from any point in the code and it will still run as if it was inside the outie
function.
Let’s use closures in another example with a little more common sense real-world scenario.
In the code above we have a function that takes arguments like rent, car payment, and car insurance. It returns a reusable anonymous function that takes an arbitrary number for salary as an input and subtracts the total of expenses from the salary.
This time under the hood, we see two copies of the anonymous
function, each with their own closure objects. And as you can notice they both have different values attached to their Closure record.
Both anonymous functions are ready to fire once we provide them the salary amount.
Developing programs this way takes some practice. You have to know functions intimately, know what first-class functions are and develop a clear mental picture of what functions look like under the hood.
Takeaways:
- Outside variables are available inside the function, made possible by the Closure record.
- JavaScript functions contain more information than just the visible typed code. Functions that are bound to variables of their containing scopes are the functions with closures.