Closure - A protective bubble
Let's break up the question that has been asked, knowing that you have the patience to read the detailed answer. :)
Below, we define a function outer
and var globalValue
at Global level.
Inside the outer
function we define function inner
and outerValue
.
Inside the inner
function we define innerValue
. To cross verify that inner
function has access to all the variables we log globalValue, outerValue and innerValue
. It logs all the three values.
However, it will fail if we try to access innerValue
anywhere else than the lexical scope of that variable.
var globalValue = 'Global Val';
function outer(){
var outerValue = 'Outer Val';
function inner(){
var innerValue = 'Inner Val';
console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
}
inner();
}
outer();
Now, we will see have a closer look to closures.
So, in the example above we have quite proved the sneakiness of the inner function
.
Now, if we would invoke inner on global level, it would return an error
because it is defined locally inside the outer
function. The work around for that is to declare a global variable ref
and store inner
as a reference.
While, JS engine execution stage starts. It invokes outer(), and it creates an execution context for the outer
function. It creates execution stack
for the outer
function.
And before the execution stack for function outer
ends it assigns the value of inner
in global var ref
.
The execution stack for function outer
has ended right now.
Even though the global execution stack
is back in action. We have access to all the variables of the function outer
and inner
through the reference of inner
function stored in global variable ref
. There you go, that is a closure
.
var globalValue = 'Global Val';
var ref;
function outer(){
var outerValue = 'Outer Val';
function inner(){
var innerValue = 'Inner Val';
console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
}
ref = inner;
}
outer();
ref();
Below we are adding one more level to it. Here there is another function innermost
which has been defined inside function inner
. However, there has to be a chain to make the closure
work.
Hence, the function value innermost
is first passed to ref2
and then in the outer
function. The value of inner
is passed to ref1
. This keeps the bubble from bursting and we are able to access all the variables even while invoking the function using reference at global level
.
var globalValue = 'Global Val';
var ref1,ref2;
function outer(){
var outerValue = 'Outer Val';
function inner(){
var innerValue = 'Inner Val';
function innermost(){
var innermostVal = 'Inner most Val' ;
console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
}
ref2 = innermost;
}
ref1 = inner;
}
outer();
ref1();
ref2();