Concept and Purpose of Immediately Invoked Function Expressions (IIFEs)
An Immediately Invoked Function Expression (IIFE) is a JavaScript function expression that executes immediately after it is defined.
This technique is primarily used to prevent variable hoisting and scope pollution, making it especially useful when writing code inside a function block. The function runs as soon as it is defined, typically being invoked right after the browser compiler loads the function.
In JavaScript, managing variable scope can be quite challenging.
When there are many global variables, conflicts may arise between developers or across different JavaScript files, causing unintended variable pollution.
Moreover, variables declared with the var
keyword or function declarations are subject to hoisting, meaning they are lifted to the top of their scope, which can introduce unexpected behaviors.
To solve these troublesome scoping issues, JavaScript developers began using coding patterns that leverage the characteristics of functions.
— Of course, in modern JavaScript, this problem is more easily resolved using modules. —
JavaScript functions have two key features:
- Variables declared inside a function block (also called the function body) are scoped locally to that function block.
- Functions can be invoked at any desired point in the code.
Developers realized that by defining a function, declaring variables inside its body, and then immediately executing that function, the variables remain scoped within the function, thereby preventing unwanted scope pollution.
This coding pattern is what we call an Immediately Invoked Function Expression (IIFE).
Here is an example of a typical IIFE, usually written as an anonymous function:
(function() { // Immediately Invoked Function Expression
let a = 1;
let b = 2;
let c = a + b;
console.log(c);
})();
let a = 2; // This 'a' does not conflict with the 'a' inside the IIFE
Notice that the function runs and prints the result to the console immediately, without being explicitly called elsewhere.
Even if you don’t yet know how to write an IIFE, this pattern effectively solves tricky scoping problems.
To restate, an IIFE is:
A coding technique that leverages JavaScript functions to prevent variable hoisting and scope pollution by writing code inside a function block that executes immediately after its definition (usually right after the browser compiler loads the function).
In the next section, we will learn how to write IIFE syntax in JavaScript.
Understanding Immediately Invoked Function Expressions (IIFEs)
As mentioned earlier, an Immediately Invoked Function Expression (IIFE) is a function expression that executes immediately after it is defined. More precisely, it refers to a function expression that is invoked right after the browser’s JavaScript compiler loads the function.
In JavaScript, functions are called using the following syntax:
functionName();
A function is called by appending parentheses ()
after the function name.
If the function accepts parameters, arguments are passed inside the parentheses like this: functionName(argument1, argument2)
.
It is important to note the difference between a function declaration and a function expression. Unlike function declarations, IIFEs are function expressions that are immediately executed. This distinction affects how the JavaScript engine parses and runs the code.
An IIFE involves:
- Defining a function, and
- Immediately invoking it by appending
()
or, if there are parameters, by passing arguments inside()
.
Let's create an IIFE step-by-step according to this order.
Define the function
function fn() { /* code */ }
The example above shows a named function declaration that defines a function.
Immediately invoke the defined function by appending ()
or (arguments)
If you simply add ()
right after a function declaration like this:
function fn() { /* code */ }();
you will get an error:
Uncaught SyntaxError: Unexpected token ')'
This error occurs because this syntax does not conform to JavaScript’s function declaration rules.
To avoid the error and create an IIFE, wrap the function declaration and invocation inside parentheses like this:
(function fn() { /* code */ }());
Here, the parentheses around the function and its invocation are not for calling the function themselves; they act as a grouping operator.
Additional explanation: Grouping operator ()
Parentheses ()
in JavaScript are not only used for calling functions but also act as grouping operators.
A grouping operator wraps an expression inside parentheses to force it to be evaluated first.
By wrapping a function declaration followed by ()
inside parentheses, the entire code becomes a function expression, which can be immediately executed. An expression is a piece of code that produces a value or performs an action.
So wrapping the function declaration and invocation in parentheses changes the syntax into an expression, which allows it to be executed immediately.
Ways to Immediately Invoke a Function in JavaScript
There are several ways to write IIFEs in JavaScript, which broadly fall into two categories:
- Using the grouping operator
()
- Using the characteristics of unary operators
Using the grouping operator ()
(function fn() {
/* code */
}());
(function fn() {
/* code */
})();
Using unary operators
!function fn() {
/* code */
}();
+function fn() {
/* code */
}();
-function fn() {
/* code */
}();
Here, !
, +
, and -
are common unary operators.
When used before a function declaration, they convert the function into an expression, which can then be immediately invoked with ()
.
In other words, this is another way to create an IIFE.
Using Immediately Invoked Function Expressions (IIFEs)
Commonly Used as Anonymous Functions
Since an IIFE is defined and invoked immediately, it often does not require a function name.
Therefore, anonymous functions are commonly used for IIFEs.
(function () {
/* code */
}());
Using anonymous functions helps avoid naming conflicts with other functions and improves code readability, especially when the function is intended for one-time use only.
Invoked Only Once and Cannot Be Called Again
Because an IIFE is a function expression that executes immediately upon definition, it cannot be called again afterward.
const fn = (function() {
console.log("This runs only once.");
}());
// Output: "This runs only once."
fn(); // Uncaught TypeError: fn is not a function
Using Parameters in an IIFE
(function(initialValue) {
let count = initialValue;
console.log(count);
}(10));
// Output: 10
You can also use an IIFE to return a value and assign it to a variable.
This allows you to immediately execute some logic and store the result.
const sum = (function(x, y) {
return x + y;
}(5, 7));
console.log(sum); // 12
In this example, the IIFE takes two parameters, adds them together, and returns the result.
The returned value is immediately assigned to the sum
variable, which you can use later in your code.