Hug Day-Feb 12th- Closures with my Lover JS (JavaScript)
As today is the hug day , I want a hug from the Js(JavaScript). So I asked my lover js to give me a hug as "one hug from the right person takes all your stress away" and for me that person is Js. But she told me she will give a hug, but I have to ask for hug in her way. So I wrote a function named giveMeAHug like this.
function giveMeAHug() {
let myJSStatement = "Hey honey! this is your hug.";
let canGiveHugAtMoment = true;
function takeHug() {
if (canGiveHugAtMoment) {
console.log(myJSStatement);
}
}
}
giveMeAHug(); // I called the function , but nothing happens .
I aksed my lover Js, why your are not giving me a hug , as you told me to write a function , I have done that and I am calling that function also, but still you are not giving a hug. To this, my js replied "Oh , you naive lover ! When will you become pro? And she give me an answer ,after listening I got stunned.
But before telling you the answer I want to ask you , as I knew you also have a crush on Js and you also trying to learn her language so to communicate with her.The later part will surely happen , but you will never beat me in loving Js. Ok, joke's apart.
Do you know why nothing happens since giveMeHug function doesn't return anything nor does it print anything in the console.And also function takeHug constitutes the main logic for the hugging but there is no way to call that inner function from outside.
So for that , we have to return takeHug function in order to call it from the outside.
function giveMeAHug() {
let myJSStatement = "Hey honey! this is your hug.";
let canGiveHugAtMoment = true;
function takeHug() {
if (canGiveHugAtMoment) {
console.log(myJSStatement);
}
}
return takeHug;
}
And now when I will call giveMeAHug() this will return me takeHug function , which I can call like this , by introducing another pair of parantheses, since to invoke/call a function , we have to give function_name_followed_by_a_pair_of_parantheses like this - functionName()
giveMeAHug()();
Output will be -
Hey honey! this is your hug.
After getting a sweet hug , I asked my Js lover is there any way to call inner function directly instead of using giveMeAHug()() every time, can I just be readyForHug and I will get a hug, since I don't like everytime I have to ask for hug like this giveMeAHug.
She replied , yes.
You know instead of calling the inner function in this way, we can also use a variable and store/assign the giveMeAHug returned function reference(i.e. original takeHug function ) to that variable and later just call that function with using the variableName just like this.
function giveMeAHug() {
let myJSStatement = "Hey honey! this is your hug.";
let canGiveHugAtMoment = true;
function takeHug() {
if (canGiveHugAtMoment) {
console.log(myJSStatement);
}
}
return takeHug;
}
// giveMeAHug()();
const readyForHug = giveMeAHug();
/*calling the giveMeAHug function and this will return innerFunction takeHug
reference and storing that reference inside a variable
named "readyForHug" so I can call it later.*/
readyForHug(); //this will give the same result.
Output will be the same -
Hey honey! this is your hug.
After getting a hug, I got a doubt. I asked Js , You told me the after function execution , all the variables stored inside that function got wiped up and we can't used them further in the code.Then how, readyForHug function(ie. actually takeHug function reference only ) accessing "myJSStatement" and "canGiveHugAtMoment". How is it possible, since I called giveMeAHug function and after executing its all variables must be wiped off and I can't be able to take access of variables inside it.
So, my Js told me that yes, you are right, after the function execution , whatever the variables who got memory allocation previously got wiped off from the memory.
But in Js, there is also a concept known as closures. And here due to closures only , takeHug function is able to access "myJSStatement" and "canGiveHugAtMoment" variables even after the giveMeAHug function (in which they are declared and assigned with a value) done with the execution.
In general term, with the help of closures , an inner function always has access to the variables and parameters of its outer function, even after the outer function has returned(means executed). Closure is a function that remembers the variables from the place where it is defined, regardless of where it is executed later. And thats why inner function has access to "myJSStatement" and "canGiveHugAtMoment" variables.
Oh, now I get it . I asked her can you show, me where does it store so I get a better picture although I get your point. So she replied , yes you can see the scopes and under the scopes you will see a closure which will be storing the variables. You can simply open Google Chrome web browser and do this -
Press Command+Option+J (Mac) or Control+Shift+J (Windows, Linux, Chrome OS) to jump straight into the Console panel.
And in the console panel just write or paste already written below code -
function giveMeAHug() {
let myJSStatement = "Hey honey! this is your hug.";
let canGiveHugAtMoment = true;
function takeHug() {
if (canGiveHugAtMoment) {
console.log(myJSStatement);
}
}
return takeHug;
}
// giveMeAHug()();
const readyForHug = giveMeAHug();
console.dir(readyForHug);
//I am using a method named dir of console to get more details.
After pasting or writing the code in the console, just hit enter, you will get something like this ƒ takeHug() , just expand it by clicking on arrow.After expanding, you will see at the very bottom [[Scopes]]: Scopes[3] , you can again expand it just by clicking it,and after expanding you will see a 3 scopes details here, and the very first one will be Closure storing those variable values. For more clearance, refer the attached picture.
After clearing all my doubts, now since I have takeHug function reference inside readyForHug variable and leveraging the closures benefit , I called readyForHug function 4 times like this.
readyForHug();
readyForHug();
readyForHug();
readyForHug();
Output will be -
Hey honey! this is your hug. Hey honey! this is your hug. Hey honey! this is your hug. Hey honey! this is your hug.
After this , Js got fed up, so she just made me to change the code to this.
function giveMeAHug() {
let myJSStatement = "Hey honey! this is your hug.";
let canGiveHugAtMoment = true;
function takeHug() {
canGiveHugAtMoment = false;
let myJSNewStatement = "Hey honey!Right now,I am working on event loops.";
if (canGiveHugAtMoment) {
console.log(myJSStatement);
} else {
console.log(myJSNewStatement);
}
}
return takeHug;
}
const readyForHug = giveMeAHug();
readyForHug();
Output will be -
Hey honey!Right now,I am working on event loops.
Now, No matter, how many times I will call this function , I will not be getting more hugs. Hug day is over for me. But you stay tuned for more such articles.