A Closer Look at Immediately Invoked Function Expressions (IIFE) in JavaScript

Written by smpnjn | Published 2022/11/06
Tech Story Tags: web-development | javascript | web | typescript | javascript-development | functional-programming | iife | javascript-tutorial

TLDRIIFEs give us an easy way to isolate variables within a function, and not globally - after which we can easily run the function immediately. Immediately invoked function expressions, or IIFE, are functions that are run as soon as you define the function. They are also useful for running async functions when a top level `await` is not available. The defensive semi-colon is added to the start of IIFE code to avoid a weird issue where the previous line doesn't have a semi-Colon, the function's last line will be used as the function name.via the TL;DR App

Immediately invoked function expressions, or IIFE, are functions that 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:

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:

(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:

(() => {
    console.log("hello world!")
})()

While the IIFEs above do not have names, you can give them names. It doesn't 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:

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

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

(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 argue our IIFE - which is x. We can pass in a value x by using the last set of parenthesize:

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.

;(() => {
    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's last line will be used as the function name. Consider this code:

let b = 5
let c = 10
let a = b + c
(function () {
    return 10
})();

If someone forgot to put a semi-colon on, 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:

c(() => {
    return 10
})()

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

Conclusion

IIFEs are commonly found in Javascript code bases and have been a useful way to perform several 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.

Also Published here


Written by smpnjn | Product, Engineering, Web
Published by HackerNoon on 2022/11/06