Bringing closure to you and JavaScript

The topic of closure can be confusing to programmers, especially since it only exists in some languages like JavaScript, Ruby, and Swift. That’s because languages have different rules for their scopes, so before we discuss what a closure is, we first need to clarify what scopes are.

If you have ever written in JavaScript before, you will notice that variables are not always accessible. Here is an example:

I created a function and set a variable hello to the string “hello”. I also wrote console.log both inside and outside the function with the hello variable. Notice that in the output, the hello variable inside the function was defined, but not the hello outside. This is because since I defined the variable in the function, then the variable’s scope exists inside the function only, meaning it can only be accessed within the function. On the other hand:

Here the variable hello is declared outside the function rather than inside and you’ll notice that both console.logs work. That is because the variable’s scope is no longer in the function and this is some how scope works in some languages. The code will look through the scope chain and start by looking for the variable in the current scope, and begin to move up the chain to its parent all the way to the root scope to see if the variable exists.

Now what if there was a way to have the program hold onto local variables in its memory even if it was outside of its scope? This is where closure comes into play. Take a look at this example:

I create a function, multiplyNumber, and in that function I create another function, multiply while passing an argument into each function. In the multiply function, I return the product of both arguments and in the multiplyNumber function I return the multiply function. In the first console.log, I pass two arguments into multiplyNumber. Then I create another function, through the multiplyNumber function, called multiplySix. Essentially I am passing in the integer 6 for the num parameter.

When I pass in the integer 5 into the function multiplySix and integers 6 and 5 in the function multiplyNumber and console.log the invoked function, they both have the same result: 30. However, there is something more interesting going on behind the scenes. As you can see in the image, I also console.dir both functions multiplySix and multiplyNumber to see the scopes of both functions. In multiplySix, there exist two scopes: Closure and Global. In multiplyNumber, there is only one scope: Global. Why does multiplySix have a closure and not multiplyNumber? What is the difference in how the functions are operated? The difference is multiplySix is holding a variable num that is equal to 6. The variable persists outside of its local environment, and that is through creating the new function multiplySix. The persistence will occur for as long as the function exists.

Now what if we just pass a variable outside of a function and use that variable in the function? Is that still considered a closure? Let’s take a look at one last example:

Here I am creating a variable set to 6. I create a function, addSix, and pass in an argument, returning the sum of that argument and six. When I pass in 5 to the function and console.log, of course the output will be 11. What makes this interesting is when I console.dir the function. As you can see in its scope, there are two scopes but instead of being Closure and Global , the scopes are actually Block and Global.

So what is the major takeaway here? Closures are not just about preserving data. Instead, it is about creating a function within another so that a function is able to use that variable outside of its local environment. As the MDN Web Docs puts it, “A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.