Functions in JS and it's use cases
Tags: javascript, beginners, programming, functional
Published: 2022-01-17 13:01:11

## Function types

1. Function declaration
2. Function expression
3. Arrow Functions
4. Immediately Invoked Function expression

## Function Declaration
```
function foo(){
     console.log("Do not use var");
}
```

- 
Function declarations are loaded before the script is loaded. This means that the function can be invoked before the function declaration.

```
foo();    //Function will be invoked

function foo(){
     console.log("Please use strict in JS");
}
```
This is because function declarations are hoisted(Hoisting in JS refers to the process in which functions, variables or classes are moved to the top of the scope for interpreting, before the execution of the script.)

- 
Function declarations also have a block scope in ["use strict"](https://javascript.info/strict-mode) mode.

```
"use strict";

if(x>18){
   
   foo();     //Will be invoked

   function foo(){
       console.log("Pineapples on pizza should be illegal.")
   }

   foo();     //Will be invoked
}

foo();     //Line 10
```
Line 10 will throw a ReferenceError.

- 
Consider the same case, without "use strict".

```
foo();     //Will not be invoked

if(x>18){
   
   foo();     //Will be invoked

   function foo(){
       console.log("Pineapples in pizza should be illegal.")
   }

   foo();     //Will be invoked
}

foo();     //Will be invoked only when if block is executed.
```
The function `foo` declaration will not be hoisted in the global scope, but within it's local scope(within the if block).

Function declarations are preferred when we want the function to available throughout it's scope for invoking.

## Function expressions

```
let foo=function(){
     console.log("Elon Musk");
}
```

- 
Function expressions basically means assigning a function to a variable.(The foo variable is referenced to an Anonymous function) Unlike Function declarations, Function expressions are not hoisted.

```
foo();     //Will not be invoked

let foo=function(){
     console.log("Elon Musk.");
}

foo();     //Will be invoked
```

- 
The function is declared when the interpreter reads the right of the assignment operator(=).

- 
Function expressions are preferred over function declarations when we want functions to have a limited scope instead of a global scope throughout the program.(They cannot be hoisted to prevent functions to be crowded in the global scope).

## Arrow Functions

```
foo=()=>{
     console.log("Web3");
}
```

- 
The arrow functions are a shorthand to writing functions. Let us understand it with the help of [`setTimeout()`](https://javascript.info/settimeout-setinterval).

```
setTimeout(foo(),2000);     //Calls foo() after 2 seconds

function foo(){
     console.log("Mark is the watcher");
}
```
Now check this out.

```
setTimeout(()=>{
     console.log("DC is underrated");
},2000);
```
Both the code snippets have the same functionality, but the latter has less lines of code and has better readability. 

```
let mulTwo = number => number * 2  
  
/*If the arrow function has only one line in the body, there is no need for curly braces.*/

mulTwo(2);     //4
```

## "this" in Arrow Functions

- 
Arrow functions do not have `this`. If used, they take the context of the outer scope.

```
const obj={
     name:"Spiderman",
     
     foo(){
          setTimeout(()=>{
               console.log(this);
          },1000);
     }
};

obj.foo();                //Output is object obj.
```
Here `this` refers to the `this` of foo().

For function expressions and function declarations the value of `this` is dynamic(It's value depends upon where the function is being called).

```
const obj={
     name:"Spiderman",
     
     foo(){
          setTimeout(function(){
               console.log(this);  
          },1000);                              
     }
};

obj.foo();          //Window object

/*Output is the window object because the function is called in the global scope.*/
```
In order for the function to have the same context as it's scope, it needs to be bound to it's current context.(Using bind function).

```
const obj={
     name:"Spiderman",
     
     foo(){
          setTimeout(function(){
               console.log(this);  
          }.bind(this),1000);                              
     }
};

obj.foo();
/*Output is the object obj because the function 
is now bound to the current context.*/
```
Since the arrow functions do not have `this`, it will use the value of `this` from it's parent scope.

## Immediately Invoked Function expression(IIFE)
An IIFE is called immediately after function is created. It is self invoking. 

```
(function(){
    console.log("Daredevil");
})();
```
Consider this scenario,

```
let sum = (function(a,b){
    return a + b;
})(5, 10);

console.log(sum);       //15

console.log(sum());     //Error
```
In the above scenario, `sum` only stores the return value of the function assigned to it, we cannot call the function elsewhere.

An IIFE can also be named, even then it cannot be called.

```
(function NWH() {
    console.log("I am a very good lawyer");
})();

NWH();      //NWH is not defined
```
IIFEs can be used if you want a function to be used only once. It is also used in closures(Click [here](https://mariusschulz.com/blog/use-cases-for-javascripts-iifes) for a detailed article).

Hope this article helped. I am new to programming and this is my first blog. Let me know how I can improve in the comments below!:D