“Closure” explained
I wrote a blog on Scope a couple of blogs before, and it took some time for me to understand the difference between Scope and Closure.
In the example below, invoking calculator() (line 13) causes “ReferenceError: calculator if not defined”. This is due to Scope. Function calculator was declared within multiplyNumbers function scope, but calculator() function was called from the global scope.
If the function calculator was declared in the global scope, calculator() can be called in the global scope. In the below, we can clearly see that the invoking calculator() (line 17) is executing calculator function that’s defined in the global scope, not the one from multiplyNumbers function scope.
Now, I changed variable declaration to “let” from “const” for global calculator function (line 3), and removed “const” from function calculator (line 11) that is defined within multiplyNumbers function. With this code, invoking multiplyNumbers(), function causes new function body to be assigned to global calculator function, as you can see with console.log(calculator) (line 20), which still calling global calculator function.
With above code, calculator(3, 5) was invoked again (line 20), and the log shows “15 is the result of ‘Multiplication’.”. Now the question is this: How is it possible for global calculator function to have access to variable operation ( line 9)? The scope chain rule should not allow global function calculator to access any variables defined within multiplyNumbers function scope.
This is where Closure comes in place. When multiplyNumbers() function was invoked (line 18), a Closure is created for global calculator function. console.dir(calculator) shows within [[scopes]], there is a Closure where this global calculator function still has access to operation variable.
Closure allows the function to have access to all of the variables that it had access to when the function was declared.
In the below, new function addNumbers was declared (line 23), and within it calculator function was redefined with “addition” operation. When addNumbers() was invoked (line 33), calculator function was redefined. It caused new Closure to be created, and now calculator function will have access to new operation value: “Addition” (line 25).
What helped me to understand Closure is that the function will have access to all of the variables that it had access to when the function was declared /re-declared.