Skip to main content

Understanding closures in Javascript -

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.

closure

Problem Statement

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

  1. Problem Statement
1let name = "Ganesh"
2
3function getMyName() {
4 console.log("Name is " + name)
5}
6
7name = "Mani"
8
9getMyName() //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

1function getMyName() {
2 let name = "Ganesh"
3
4 return function() {
5 console.log(name)
6 }
7}
8
9let name = "Mani"
10
11// create a function
12let myname = getMyName()
13
14// call it
15myname() // 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.

lexical env

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.

1function User() {
2 this.firstname = "John"
3
4 this.lastName = "Robert"
5}
6
7User.prototype.getFirstName = function getFirstName() {
8 console.log(this.firstname)
9}
10
11User.prototype.getLastname = function getLastname() {
12 console.log(this.lastName)
13}
14
15User.prototype.showFullName = function showFullName() {
16 console.log(this.firstname + " " + this.lastName)
17}
18
19module.exports = User

we are creating a function called user and add the function getFirstNamegetLastName and showFullName for the particular user function and access the function variable with thiskeyword.

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

1let User = require("./user")
2
3let data = new User()
4data.showFullName()

it will show me something like "John Robert"

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

1function User() {
2 let firstName = "Will"
3
4 let lastName = "Smith"
5
6 return {
7 getFirstName: function() {
8 console.log(firstName)
9 },
10
11 getLastName: function() {
12 console.log(lastName)
13 },
14
15 showFullName: function() {
16 console.log(firstName + " " + lastName)
17 },
18 }
19}
20
21module.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

1//using Closure in Javascript
2
3let userClosure = require("./user_closure")
4
5let closureresult = userClosure()
6
7closureresult.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 thiskeyword.

Quiz :

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

1function doIncrement() {
2 let counter = 0
3
4 return function() {
5 counter++
6 return counter
7 }
8}
9
10let increment = doIncrement()
11
12console.log(increment())
13console.log(increment())
14console.log(increment())
15//What is the result ?

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

Comments

Popular posts from this blog

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functio...

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.compon...

How to solve Puppeteer TimeoutError: Navigation timeout of 30000 ms exceeded

During the automation of multiple tasks on my job and personal projects, i decided to move on  Puppeteer  instead of the old school PhantomJS. One of the most usual problems with pages that contain a lot of content, because of the ads, images etc. is the load time, an exception is thrown (specifically the TimeoutError) after a page takes more than 30000ms (30 seconds) to load totally. To solve this problem, you will have 2 options, either to increase this timeout in the configuration or remove it at all. Personally, i prefer to remove the limit as i know that the pages that i work with will end up loading someday. In this article, i'll explain you briefly 2 ways to bypass this limitation. A. Globally on the tab The option that i prefer, as i browse multiple pages in the same tab, is to remove the timeout limit on the tab that i use to browse. For example, to remove the limit you should add: await page . setDefaultNavigationTimeout ( 0 ) ;  COPY SNIPPET The setDefaultNav...