Javascript Immediately invoked function expressions (IIFE)
Tags: webdev, javascript, tutorial
Published: 2022-11-06 20:10:19

Immediately invoked function expressions, or IIFE, are functions which are run as soon as you define the function. You may also see people refer to them as anonymous functions. They give us an easy way to isolate variables within a function, and not globally - after which we can easily run the function immediately. They are also useful for running async functions, when a top level `await` is not available.

While we usually define functions like this:
```javascript
let x = () => {
    console.log("hello");
}
let y = function() {
    console.log("world");

}

function z() {
    console.log("!");
}

x(); y(); z();
```

Defining an IIFE means invoking the function as we write it. So we can define an IIFE like this:
```javascript
(function() {
    console.log("hello world!")
})()
```

This function is anonymous (it has no name) - and it runs immediately. You can also run it using arrow notation, like this:
```javascript
(() => {
    console.log("hello world!")
})()
```

While the IIFEs above to do not have names, you **can** give them names. It doesn't really make sense, though, since you can't call them anywhere else. Once the function is created and called in this format, it cannot be used anywhere else. That means that in the example below, trying to call `myFunction()` somewhere else will not work:

```javascript
(function myFunction() {
    console.log("hello world!")
})()
```

Anonymous or Immediately invoked function expressions can be used to encapsulate async behaviour. You can still make an IIFE asynchronous by using the `async` keyword:

```javascript
(async () => {
    console.log("hello world!")
})()
```
## Giving arguments to IIFEs in Javascript
We can pass variables straight into an IIFE using the expected format. For example, below we have an argument in our IIFE - which is `x`. We can pass in a value for `x` by using the last set of parenthesise:

```javascript
let getNumber = 10;
(function(x) {
    console.log(x + 10)
})(getNumber) // console logs 20
```
## The defensive semi colon in IIFEs
You may sometimes see the following code when IIFEs are defined where a semi colon is added to the start.
```javascript
;(() => {
    return 10;
})
```

This seems confusing but it's to avoid a weird issue where, if the previous line doesn't have a semi colon, the function last line will be used as the function name. Consider this code:
```javascript
let b = 5
let c = 10
let a = b + c
(function () {
    return 10
})();
```

If someone forgot to put a semi colon on `let a = b + c`, or if you imported the IIFE onto a line where the previous one did not contain a semi colon, you may run into some weird bugs. In the above example, you'll get the error `Uncaught TypeError: c is not a function`. This is because the code interprets this as trying to run the `c` function. In essence, the code sees this:
```javascript
c(() => {
    return 10
})()
```

So defensive semi colons at the start of IIFEs is an easy way to avoid this scenario.

## Conclusion

IIFEs are commonly found in Javascript code bases and have been a useful way to perform a number of things like asynchronous code and scoping variables or code within a specific function block. While there are now other ways to achieve this in Javascript, you're still going to see these all over the place - so understanding how they work is important.