YOU CAN RETURN A FUNCTION FROM A FUNCTION!
This is possible because functions are first-class objects.
function createFunction() {
function multiplyBy2 (num){
return num*2;
}
return multiplyBy2;
}
const generatedFunc = createFunction();
const result = generatedFunc(3); // 6
Returning a function, storing it in a variable(sorry, I mean const) and invoking the returned function from outside where it is defined. Well, Looks great!!
But wait! what if our returned function is using data of its parent function? Look at the below example.
function outer (){
let counter = 0;
function incrementCounter (){ counter ++; }
return incrementCounter;
}
const myNewFunction = outer();
myNewFunction();
myNewFunction();
Here, when our returned function is invoked we try to access a variable that is already dead! I mean, trying to access a variable from a function that already got executed, popped out of call stack, and whose local memory is cleared. There is no way of accessing that variable right?
But, this is JS! anything can happen, lol.
Okay! let's understand what is happening.
Attention! When a function is returned a datastore is created if the outer function has any data which is being referenced by inner function(returned fn). This datastore is called closure. I usually call it a backpack
One more time: A closure is a 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.[MDN]
Note that the data inside a closure is persistent and referred.
One more takeaway! See below example:
function outer (){
let counter = 0;
function incrementCounter (){
counter ++;
}
return incrementCounter;
}
const myNewFunction = outer();
myNewFunction();
myNewFunction();
const anotherFunction = outer();
anotherFunction();
anotherFunction();
Here we create two different backpacks(closures) for two variables myNewFunction and anotherFunction. This happens because we have two different execution contexts while assigning returned functions to variables.
Application of closures: Asynchronous JS, Iterators and generators, and many more.
Top comments (0)