Closer look at Closures.

Anup Verma
VectoScalar
4 min readJan 8, 2023

--

‘closure’ is the combination of a function bundled together with references to its surrounding state (Lexical Environment).

Before we move any further , few things to be aware in order to understand Closures are :-

1- Execution Context

2- Call Stack

3- Scope Chain

The Execution Context.

Source : GIPHY

There are two types of Execution Context :-

1- Global Execution Context (Global EC )

2- Local Execution Context (Local EC )

const name = 'Anup Verma'
function callMe(a,b){
let x = 5;
console.log('params :: ',a,b,'name :: ',name ,'x :: ',x);
}
callMe(2,3);

Global and Local E.C for the above snippet would look like:-

global execution context and local execution context in play
Global and Local E.C in action

NOTE :

The Local E.C of a function contains information regarding its “Arguments”, “this” keyword and “variables” declared inside it.

But , in case of an Arrow Function and Anonymous function , ‘this’ keyword and ‘Arguments’ are NOT present.

The Call Stack.

Source : GIPHY

The place where all the Magic Happens.

The call stack is where each and every execution context is placed in a form of a stack and is executed and “popped out” once it is done executing.

Consider the following example.

const counting = function(){
let count = 0;
return function(){
count++;
console.log('count :: ', count);
}
}
const counter = counting();

counter(); //count :: 1
counter(); //count :: 2
counter(); //count :: 3

The Call Stack and the Execution contexts working together.

Call stack when counting is executing
Left : After counting has finished executing , it is popped off from the Call Stack

As you can see from the bottom two images , even though the counting function is no more present in the call stack , then too the “counter function” has the access to the variables in the Environment in which it was created
(i.e counting()).

Closures.

Source : GIPHY

Any function always has the access to the variable environments of the Execution Context in which the function was created , Even after that Execution context is Gone.

“Counter()” function was born in the Execution context of ‘Counting()’ function , hence this ‘Counter()’ function will get access to the variable environment (i.e “count” )

WHAT is Closure ?

Closure is this Variable Environment Attached to the function , exactly as it was at the time and place when the function was created and the scope chain is ‘Preserved’ through this closure.

Thanks to this ‘closure’ a function does not lose connection to variables that existed at the function’s birth place.

Although this is one of those topics which people tend to forget , here are some intuitive examples/analogies to help you understand what closures are all about.

Informal Definition(s)

A closure gives a function ‘Access’ to all the variables of its parent function , even after the parent function has returned. The function keeps a “reference” to its outer SCOPE , which “preserves” the scope chain throughout.

It’s like a person who doesn’t lose connection to their HOME-TOWN , in this analogy,
Person -> Function
Home town -> Parent Scope

PERSON — — —> Connection — — —> HOME-TOWN( — — →Variables)

And the person does not lose connection to the variables stored in its parent scope i.e home town.

CONCLUSION

We don’t have to create “closures” Manually, this is something JavaScript does completely Automatically, also there is no way we can access these ‘closed-over’ variables explicitly i.e because “A Closure is NOT a tangible JavaScript Object.”

--

--