Closures, Functions & Event Listener in JavaScript

Harshit Bansal's photo
·

5 min read

Closures, Functions & Event Listener in JavaScript

Closures

Let’s see a code snippet first

function x(){
    var a = 7;
    function y(){
        console.log(a);
    }
    y();
}
x();

When we will run this program we know that the output is going to be 7 because when we are trying to access a from the function y then it is inside the Closure of function x.

What is Closure ?

Closure basically means that a function bind together with its lexical environment. Here function x is bind to function y with its lexical environment as the scope of function y. The function y was bind to the variables of x, so that means it forms a closure and it has access to its parents's lexical scope.

In JavaScript, we can pass a function as an argument in a function or we can return any function from a function. So let’s see a piece of code.

function x(){
    var a = 7;
    function y(){
        console.log(a);
    }
    return y;
}

var z = x();

function b(){
    z();
}
b();

In this code, we return the function y from x and store it in a variable z and when we will run z in a function b it’ll run the function y as it is stored in z. So here it’ll print 7 only as it does not changes its scope even after getting stored in a new variable or getting called in another function.

Closures can also work in nesting, we can access the lexical scopes as deep as possible.

function x(){
    var a = 5;
    function y(){
        var b = 10
        function z(){
            console.log(a, b);
        }
        z();
    }
    y();
}
x();

So in this code, when we try to see the scope of the function z, it looks like this

Here we can see that z have the closure of x and y in its lexical scope.

Uses of Closure

  • Module Design Pattern

  • Currying

  • Functions like once

  • Memoize

  • Maintaining state in async world

  • setTimeouts

  • Iterators

    and many more…


Functions

  • Function Statement/Function Declaration → When a function is created using the function keyword and the name of the function.
function statement(){
    console.log("This is a function statement")
}
  • Function Expression → When a function is created and assigned to any variable and then the function acts like a variable.
var expression = function(){
    console.log("This is a function expression")
}

What is the difference between Function Statement & Function Expression ?

The major difference between these two is Hoisting. So if we try to call the functions in both case before initializing them then the output will be following in both of the cases

So during the hoisting phase during the memory creation phase, a is created a memory and this function is assigned to a, but in case of a function expression, this b is treated like any other variable. It is assigned undefined initially until the code hits this line itself. So when the JavaScript Engine executes this line by line and reach to this line, then only this function is assigned to this variable b until then it is undefined.

  • Anonymous Functions → Any function without a name, they do not have their own identity, so if you create and call them directly, it’ll throw a SyntaxError. So they are used in a place where functions are used as values.

      function(){
          console.log(a)
      }
    
  • Named Function Expression → Function expression without any name of the function, means an anonymous function assigned to a variable.

      var expression = function xyz(){
          console.log("This is a named function expression")
      }
    
  • First Class Functions → The functions, which take another functions as arguments. Functions in JavaScript can be passed as an argument to the other functions and can also be returned from the other functions. They are called First Class Functions or First Class Citizens.

What is the difference between parameters and arguments ?

While creating a function whenever we place any identifier in the parenthesis, it is known as a function parameter , this is the local variable in the function scope. The values which are passed with the function during the function invocation are known as the function arguments, these values are assigned to function parameters.

function add(param1, param2){ //Parameters
    console.log(param1 + param2);
}

add(2, 4); //Arguments
  • Callback Functions → If we have a function, let's call it X, let us pass another function named Y inside this. Then here function Y is the callback function. This function Y is called back sometime later in your code.

      setTimeout(function cb(){
          console.log("This is a callback function");
      }, 5000);
    
      //In this code cb is the callback function which will be called after 5 seconds.
    

Event Listeners

Let’s understand with the help of an example.

<button id="clickMe">Click Me</button>

Here, we have a button with its id=clickMe. So now let’s attach a click handler to this button.

document.getElementById("clickMe").addEventListener("click", function xyz(){
    console.log("Button Clicked")
})

This piece of code means when JavaScript will execute this line so it will pick up this button, Click Me, and it will add an event listener that is click and what will happen if that event occurs is that it will call this callback function xyz. So this callback function is stored in the memory and will automatically come into our call stack once this button is clicked.

After adding an event listener, we also need to remove an event listener as sometimes, it is possible that a program might have a number of event listeners which might make the program heavy due to consumption of memory so that is the main reason why we remove event listeners when we are not using them.