DEV Community

GaneshMani
GaneshMani

Posted on • Originally published at cloudnweb.dev

Understanding closures in Javascript - Javascript weekly

For regular updates, subscribe to weekly newsletter, Weekly Updates.

In this article, we will see what closure is and why do we need something like closure, Understanding closures in Javascript - Javascript weekly

Previous Article : https://cloudnweb.dev/2019/06/understanding-generators-in-javascript-javascript-weekly/

What is Closure?

In simple terms, Closure is nothing but a function which is defined inside another function. the closure has access to all the local variables, outside function variables and global variables.

Problem Statement

To understand this in a better way, consider the following result of code.

  1. Problem Statement
let name = "Ganesh";

function getMyName() {
  console.log("Name is "+name);
}

name = "Mani";

getMyName(); //what will be the output here?

This kind of scenario is common in web development(front-end as well as backend). we will define a function and call the function later some point of time.

2. Problem Statement

function getMyName() {
  let name = "Ganesh";

  return function() {
    console.log(name);
  };
}

let name = "Mani";

// create a function
let myname = getMyName();

// call it
myname(); // What will it show? 

To understand this concept, first, we need to understand the concept of Lexical Environment

Lexical Environment

Lexical Environment is nothing but maintaining the state of the particular function and its outer environment state, variables.

Every inner function will have a local variable, inner function can also access the parent function variable and global variable.

Maintaining the scope of the particular function is nothing but a Lexical Environment.

Coming back to Problem Statements...

Now, if we come back to the problem statements, the problem statement #1 would return the value as "Mani"

Because ,The value gets updated since we have defined it as Global Variable.

Now, in Problem statement #2, we have defined a function called getMyName(). inside the function, we have defined a variable called name which is nothing but a parent function variable.

we are returning a function from the getMyName() function.

Now, if we define the same variable called name in the global context and execute the getMyName().

it won't change the value of it. because getMyName() returning a function which is nothing but a Closure will hold the variable state and value for the particular environment

https://output.jsbin.com/qikuginowe

javascript first look inside the inner function, then it will look in the parent function. finally, it will go look in the global variables.

Closure - Practical Implementation

Using Closure instead of objects

If you are familiar with OOPS concepts, you will know that concept of "this", which will refer the context of the class

Let's try to write a function using OO concept and then we will see how we can rewrite that with Closures.

function User(){

  this.firstname = "John";

  this.lastName = "Robert";
}

User.prototype.getFirstName = function getFirstName() {
  console.log(this.firstname);
}

User.prototype.getLastname = function getLastname() {
 console.log(this.lastName);
}

User.prototype.showFullName = function showFullName() {
   console.log(this.firstname+" "+this.lastName);
}

module.exports = User;

we are creating a function called user and add the function getFirstName, getLastName and showFullName for the particular user function and access the function variable with this keyword.

To call this particular function we need to create an new instance of it and call the particular function


let User = require('./user');

let data = new User();
data.showFullName();

it will show me something like "John Robert"

Now, let's see how we can rewrite this with Closures

function User() {

  let firstName = "Will";

  let lastName = "Smith";

  return { 
   getFirstName : function () {
    console.log(firstName);
  },

   getLastName: function () {
      console.log(lastName);
    },

    showFullName :function () {
      console.log(firstName+" "+lastName);
    }
  }
}

module.exports = User;

we are defining a user function like we did before, then instead of binding the function. we are returning those function from the parent function user.

Note : return functions are nothing but closures.

Now, if i want to call this function , we have to do something like

//using Closure in Javascript

let userClosure = require('./user_closure');

let closureresult = userClosure();

closureresult.showFullName()

it will return "Will Smith" as output.

This is one of the real-time use cases where can try to implement Closures instead of going with this keyword.

Quiz :

Try to solve this problem and comment your result in this post and explain me how it works.

function doIncrement(){
  let counter = 0;

  return function(){
    counter ++;
    return counter; 
  }
}

let increment = doIncrement();

console.log(increment());
console.log(increment());
console.log(increment());
//What is the result ?

That's it for this week. try to implement this in a real time usecases, so that you can grab the concept out of it.

Reference :

https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

we will see some other features of javascript in upcoming articles.

Until then, Happy Coding :-)

Top comments (2)

Collapse
 
kor3k profile image
kor3k • Edited

1 2 3 because the scope of doIncrement() persists between increment() calls, which makes counter static-like variable

Collapse
 
ganeshmani profile image
GaneshMani

Great