DEV Community

Pritam Kumar
Pritam Kumar

Posted on

Closures in JavaScirpt

Hello, Everyone! Hope You all are doing well.

Table of Contents

  • What is Scope?
  • What is Global, Block and Function scope?
  • What is Lexical Scope?
  • What is Closures?

In this Blog, I'll be writing about Closures, one of the confusing topic in JavaScript. And I'm sure that every JavaScript programmer encountered this name while learning JavaScript Language.

To understand Closures in better way. Here's is prerequisites to know. But don't worry if you don't know these concepts, I'm also writing about these Topics Such as Scope, Block scope, Function scope, Lexical Scope as mentioned above.

Let's Start with Scope.

Scope

The simple meaning of Scope is accessibility of variable from where is defined in JavaScript program.

Let's Understand with example.

 let a = "JavaScript";
 console.log(a); // JavaScirpt
Enter fullscreen mode Exit fullscreen mode

In the above example, It can be easily accessible. That's ok
But If we declare a variable inside a if block.

if (true) {
  let a = 'JavaScript';
}

console.log(a); //  ReferenceError: a is not defined
Enter fullscreen mode Exit fullscreen mode

The above example will throw an ReferenceError: a is not defined, Because, if code block created scope with variable that only accessible inside that block only.

Global Scope

If The variable declared outside of any other scope, and that variable can be access to any other scope.

var a = 5;
var b = 5;

function sum() {
  if (true) {
    const sum = a + b;
    console.log(sum); // 10
  }
}
sum();
Enter fullscreen mode Exit fullscreen mode

In the above example, I declare two variable a, b and assign a value 5. The global variable accessed inside other scope, That's why it logs sum = 10

Block Scope

When ES6 Introduced, Two new keyword were introduced to declare variable in JavaScirpt let and const, Both are block scope keyword. That can be only access inside that block only.

if (true) {
  const message = 'Hello JavaScript';
  console.log(message); // 'Hello JavaScript'
}
console.log(message); // ReferenceError
Enter fullscreen mode Exit fullscreen mode

In the first log, It prints Hello JavaScript, because we are accessing inside that block but if we try to access outside of block it will throw an ReferenceError.

Note:- The code block for, while also create block scope.

Note: - var is not block scope.

if (true) {
  var message = 'Hello JavaScript';
}
console.log(message); 'Hello JavaScript'

Enter fullscreen mode Exit fullscreen mode

In case of var keyword, if {} code block does not create a scope. That's why we're accessed message variable outside of the if block.

Function Scope

A JavaScript functions create scope with all variables (let, const, and var) that are only accessible inside that function body.

function sum() {
  var a = 5;
  let b = 5;
  const c = 5;
}
sum();

console.log(a, b, c); // ReferenceError: a is not defined

Enter fullscreen mode Exit fullscreen mode

Lexical Scope

Let's start with an example

let myName = 'Pritam';

function one() {
  let age = 15;

  function two() {
    let address = 'Hazaribagh';

    let bio = `My name is ${myName}. and age is ${age}, and Address is ${address}`;

    console.log(bio); // My name is Pritam. and age is 15, and Address is Hazaribagh

  }

  two();
}

one();

Enter fullscreen mode Exit fullscreen mode

In the Above Example

The function two() can access of it's Parent scopes variables,
also can access variable of global scope. But How? How a function scope has access of it's outer function scope. Let's know about it.

The answer is Because of Lexical scope / Lexical Environment

In the concept of Lexical scope, inner function has access of outer function's scopes.

But How it works? , How it remembers?

In JavaScript, Whenever a function created, It make reference of it's lexical variable due to an internal hidden property
[[Environment]].

Note: All function has [[Environment]] property.

Closures

A Closures is the combination of function bundle together with reference of It's lexical environment.

OR

A Closures allows you access of lexical scope even outside of it's lexical scope.

Note: - Every time Closures form when function created.

Let's Understand with an example.

function outerFunc() {
  let outerVar = 'I am Developer!';
  function innerFunc() {
    console.log(outerVar); // => logs "I am outside!"
  }
  innerFunc();
}

outerFunc();
Enter fullscreen mode Exit fullscreen mode

In the above example, due to lexical scope, innerFunc() has access of It's lexical variable. That we know very well.

Now let's make changes on program, innerFunc() invoked to be outside of outerFunc() scope or lexical scope. I mean, in other function.

function outerFunc() {
  let outerVar = 'I am Developer!';
  function innerFunc() {
    console.log(outerVar); // => logs "I am outside!"
  }
 return innerFunc
}

function newFunc() {
  const myInnerFunc = outerFunc();
  myInnerFunc();
}
 newFunc()

Enter fullscreen mode Exit fullscreen mode

In this case innerFunc has still access of its lexical scope variable (outerVar), even executed outside the scope of outerFunc(). This is case, closure comes into picture. Due to closure the innerFunc remembers it's lexical scope variable from the place where it is defined. No matter, the innerFunc invoked outside of the scope.

I hope this will give you an basic understanding of Closures.

References:

Thank you for reading.

Discussion (2)

Collapse
lannisterrr profile image
siddhant pandey

Great work, keep it up.

Collapse
sardor_ulmasov_79e00b4adf profile image
Sardor Ulmasov

Great work