JavaScript Closures Fun
JavaScript closures are fun. Not just because they're are sometimes hard to understand, but they make interview questions interesting to tackle. Today I am going to write about one such JavaScript interview question involving nested closures. You may probably find it easy to reason about once solution is presented, but it may not occur to most people on how to solve a problem on first gaze.
Without further ado, the problem I present is, (This is not the problem I wrote, I found it on the internet a while ago)
Given the following statement, write a code which will present a result of x+y
var result = sumNumbers(x)(y)
When I first saw the problem, I was like what is this? How can you ever make something like this work? However, it stumped me too and some help from my colleague, I realized that this was a classic closure problem.
Trick here is to nest one closure inside another and return closure was a return type out of that closure. Confusing? Let's see an example.
function sumNumber(x) {
return function(y) {
return x + y
}
}
In the above example we first make call to function sumNumber
with first argument, say x
, which returns a closure which takes an input y
. Since JavaScript closure captures the passed value, the inner closure thus retains the value of passed first argument.
For example, when you call sumNumber(10)
, the function returns following closure which takes single argument as an input
function(y) {
return 10 + y
}
Now remember, that this is a closure and since JavaScript treats closures as first class function, you may store it in a variable. (But it's still a closure). So in a lengthy version you can do it like this.
// Returns closure which returns y + 10
var intermediateClosure = sumNumber(10)
//Now you have a closure which takes single argument. In this case y. Thus when passed, this intermediate closure will return the value y + 10
// finalResult is 12
var finalResult = intermediateClosure(2)
// In short this can also be written eliminating step to assign intermediate closure to variable
// finalResult is again 12
var finalResult = sumNumber(10)(2)
The reason it works is because closure captures the value thus passed at the given moment. When you pass the initial
x
, the inner closure thus returned already has thisx
stored which is then used to compute the final sum.
As a closing note, let's spice it up a bit by adding one more argument.
function sumThreeNumber(x) {
return function(y) {
return function(z) {
return x + y + z
}
}
}
Here, idea is same, but it gets extended to the next level.
- We call the function
sumThreeNumber
with argumentx
. This method captures thex
and returns another function which takes single argumenty
- When we call this returned closure with value
y
, it capturesy
and returns another closure which takes single argumentz
- When we call the third and last closure with argument
z
, it has captured all the previously passed values and returns the sum
Let's break this up in smaller parts.
// Captured x = 3
var closureFirst = sumThreeNumber(3)
// Captured x = 3, y = 5
var closureSecond = closureFirst(5)
// Already captured x and y. Takes z and returns the sum of all three input numbers
var result = closureSecond(2) // result = 10
This is definitely not an extensive post on JavaScript closures which is altogether different concept to understand. Of course there are really good posts out there with clearer examples and how closures work under the hood. The aim of this post is to show how you can use JavaScript closures to create interesting problems. As usual, let me know if you have any further questions. Happy to Help!