Immediately Invoked Function Expressions [IIFE's]
Tags: javascript, beginners, codenewbie, webdev
Published: 2020-02-08 15:23:51

## What are IIFE's? :confused:

An immediately invoked function expression [IIFE] is a function, which runs as soon as it is created.

**Whoa! that seems dope.** 

☐ So, can `IIFE's` be **named**?
☐ Can we **assign** it to a variable?
☐ Will these functions be **hoisted**? 
☐ Do these functions allow **closures**? 

Cool, we will answer all these questions and some more, further in this post. :smile:

**How to declare an IIFE?**

Well, there is only one thing we can do, ie.. **declare**, but we cannot **invoke** it.

We just need to wrap a normal anonymous function in a parenthesis `()` and then append with `()`. We can also pass any arguments if needed.

```javascript
(function sayHi(name){
	return `Hi ${name}`;
}) ('bruce');
```

If we run the above snippet, we will get -> "Hi bruce" without even invoking.
If we try to invoke it like a normal function, it will throw a 

```javascript
 sayHi(`BRUCE`);   //Uncaught ReferenceError: sayHi is not defined
```

### There are many ways to declare an IIFE :grin:
 
**IIFE using Unary operators:**

```javascript
-(function() {
  // do something
})()

~(function() {
  // do something
})()

!(function() {
  // do something
})()
```

**Named IIFE:**

```javascript
(function doSomething() {
  // do something
})()
```

**IIFE using semicolons:**

```javascript
;(function() {
  // do something
})()
```

**IIFE using arrow functions:**

```javascript
( () => {
	// do domething
})();
```

**Why do we need IIFE?** 🤔

Well, there are some cases where you want to achieve some or all of the below points:

- Need a function that is not accessible anymore after being invoked.
- Need a function whose variables are not accessible outside of it.
  - You can use block-scoped variables or `let` and `const` depending on the use 
    case.
- When you don't want to pollute the global object.

### Let's see an example where we can use IIFE :smile:

Say you need a function that returns random `Id` every time you call it.

> Well, yes we can use generators and there are many ways we can do this, but we will see how to do that using IIFE.

Let's make a function that returns an Id concatenated with a counter so that it is unique.

```javascript
function(){
  ++count; 
  return `Id ${count}`
}
```
Now, we can wrap this function in an `IIFE` called `IdMaker`:

```javascript
const IdMaker = (function(){
  let count = 0;
    function(){
      ++count; 
      return `Id ${count}`;
    }
}) ();
```

Now, we just return the function that increases the count and returns it:

```javascript
const IdMaker = (function(){
  let count = 0;
    return function(){
      ++count; 
      return `Id ${count}`;
    }
}) ();

console.log(IdMaker()); // Id 1
console.log(IdMaker()); // Id 2
console.log(IdMaker()); // Id 3
```

**Things we have learned so far:** 💡

:heavy_check_mark: We can return functions in `IIFE` just like normal functions.
:heavy_check_mark: And we can also achieve **closures** in an `IIFE`.
:heavy_check_mark: No, `IIFE's` are not hoisted. Hoisting is good but we should take care of when to and when not to.
:heavy_check_mark: Yes, we can assign `IIFE's` to a variable but that won't hoist them.

### I don't understand what's happening :confused:

The basic idea here is not to pollute global object ie.. not to use a variable and a normal function which will be hoisted.

So, if we were to do this using normal functions then the variable `count` would be a global variable and then the function also would be hoisted.

So, by creating an `IIFE`:

- Variable `count` is created when we call `IdMaker()` the first time.
- The next time we call `IdMaker()` it just runs from the same memory because we 
  have another function inside the IIFE and we can access that function and 
  `count` is not created again.
- So, when we invoke the `IIFE` using `IdMaker()` we are actually invoking the 
  counter function inside the `IIFE` but not the `IIFE` itself.

**Note 📗 :** _We cannot invoke an `IIFE`, it only runs once when it is created. But it does allow the concept of **closures**._🔥


### Wrapping up

Now, we know:
:heavy_check_mark: What are IIFEs?
:heavy_check_mark: Why do we need them?
:heavy_check_mark: How to use them? and When to use them? 

Hope! this post helped you understand the concept of IIFE's :+1:

Stay tuned for further posts in this series. :smile:

Thank you!