This blog will give another perspective on how closures work, it's continuation of the previous blog. So do give that one a read which will clarify most of the concepts and this will be a cherry on top.
Let's take the same example as in the previous post. But, let's write it down in a different way. The output is the same.
function outer() {
function inner(a) {
function cb() {
console.log(a);
}
setTimeout(cb, a*1000);
}
for(var i=1; i<=5; i++) {
inner(i);
}
console.log("I run first")
}
outer();
When the for
loop is run, each time an execution context is created of inner
function in the call stack. When the inner
function is called, function cb
is allocated memory and setTimeout
is run. Even before setTimeout
is run, there's a bond formed between inner
and cb
as a
will be used in the future by cb
. So, when cb
is stored in the window with a timer attached to it, it also has backpack that has the value of a
. When called after a second, it finds a
in that backpack and that backpack is nothing but closure. Since inner
is called 5 times and each time a new cb
is created, the backpacks are different for each one of the cb
with different timers.
Now, let's tweak the code a little bit.
function outer() {
function cb() {
console.log(a);
}
function inner(a){
setTimeout(cb, a*1000);
}
for(var i=1; i<=5; i++) {
inner(i);
}
console.log("I run first")
}
outer();
Take moment and guess what will be the output. Run it using an IDE and take a look. You'll get an error saying a
is not defined. When cb
is ready to be executed, it cannot find a
because its not in its parent function scope. cb
and inner
are totally different functions and they have no relation. That will only work if you pass the value of a
to cb
and define another callback function inside the inner
function. Then you are sending the value into the scope of cb
.
And that's all about closures.
Top comments (0)