Demystifying Javascript Closures
Javascript Closures made easy
If you have been writing javascript for a little while you have probably heard of closures. But do you understand them? Closures are a fundamental concept that every javascript developer should know and understand. Closure questions are also popular interview questions that could determine whether you land that dream job or not and at what salary. If you can’t answer “What is a Closure?” you may get the job but likely at a much lower salary. Don’t let Closures keep you down.
Closures are created anytime a function is created and is the combination of the function and its surrounding state or scope of the function. In order to use closures, we need to define a function inside another function and return it. The returned function(inner function) will still have access to the scope created by the surrounding function(outer function) and any variables within it after it is returned.
Closure Examples
Let’s see closures in action by creating a counter function that when called increases the count returned by one starting from zero:
const initializeCounter = () => { //Outer function
let count = 0
// The inner counter function returned has access to the count variable.
return () => {
count += 1
return count
}
}
const counter = initializeCounter()
console.log(counter())
// => 1
console.log(counter())
// => 2
console.log(counter())
// => 3
console.log(counter())
// => 4
console.log(count)
// => undefined
By returning the function on line 4 and storing it in the counter variable we have created a closure around the counter function that always has access to the count variable. Take note that nothing but the counter function can see or increment the count variable and is undefined outside of the counter function. We have encapsulated the count variable inside the closure.
In another example we will create a function that multiplies a number by another number that is passed into the function:
// Pass in the multiplier number when we create the closure
const multiplyBy = (multiplier) => {
// The inner function can access the original function argument and takes any number as an argument
return (number) => {
return number * multiplier
}
}
const multiplyByTwo = multiplyBy(2)
console.log(multiplyByTwo(2))
// => 4
console.log(multiplyByTwo(4))
// => 8
console.log(multiplyByTwo(10))
// => 20
console.log(multiplyByTwo(100))
// => 200
One important thing to note is that the multiplyByTwo
function that was returned can still access the original argument that was passed into the multiplyBy
function. This allows us to multiply by whatever number was passed for the life of the return function.
There really isn’t much more to closures than this. They are a simple concept that is easy to get confused by. If you are ever in a situation where closures are giving you problems, ask yourself where did this function come from(how was it created or what returned it) and what can this function access(what is the lexical scope of this function). As always leave any questions or comments below and Happy Coding!
Other articles on Closures
EasyCoders always wants to give you the best resources, so here are some other good reads.