Codementor Events

Closures - A protective bubble

Published Sep 26, 2017Last updated Mar 24, 2018
Closures - A protective bubble

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 i.e. globalValue, outerValue,innerValue.

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.

The reason that it throws an error is because as execution reaches inner()

var globalValue = 'Global Val';
function outer(){
        var outerValue = 'Outer Val';
        function inner(){
            var innerValue = 'Inner Val';
            console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
    }
 
}
    inner(); // error
    outer();

The work around for that is to declare a global variable ref1.

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 ends it assigns the value of inner in global var ref.
The outer execution stack 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. Yes, although it is useless but it will get even clearer to understand how the levels of passing the value of function innermost to reference variable ref2 creates a closure again.

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();

Closures also work in case the parameter value is passed to the function.

var globalValue = 'Global Val';
var ref;
function outer(){
    var outerValue = 'Outer Val';
    function inner(parameter){
        var innerValue = 'Inner Val';
        console.log(globalValue + '\n' + outerValue + '\n' + innerValue + '\n' + parameter);
    }
    ref = inner;
}


outer();
ref();

Putting closures to work

Create private variables.
Below we have created a constructor function pubName and passed a parameter pName. It has a variable storing the name value in it from the argument being passed.
A new instance of the pubName function is created using var xMen = new pubName('wolverine');.
When a new instance is created, the variable name stays private to the newly created object xMen. However, we have defined a method which helps us to access the private variable using the closure which is created.
When we invoke the method xMen.getName(); it returns the value wolverine.

function pubName(pName){
    var name = pName; 
    this.getName= function(){
        return name; 
    }
}

var xMen = new pubName('wolverine');

Discover and read more posts from sagarmunjal
get started
post comments1Reply
Laravel Developer
7 years ago

Good.