Immediately Invoked Function Expressions (IIFEs)

Contact Us or call 1-877-932-8228
Immediately Invoked Function Expressions (IIFEs)

Immediately Invoked Function Expressions (IIFEs)

Earlier in this lesson we looked at function expressions, creating a function like this:

var Foo = function(bar) {
	return bar + 3;
}

We might then call the function like this:

document.write(foo(4));

which would write 7 to the screen.

Because JavaScript treats any code wrapped in parentheses as an expression, another way to write a function expression, and to invoke it immediately, is like this, as an Immediately-Invoked Function Expression:

(function(bar) {
	return bar + 3;
})(4);

Our function - an anonymous function, in this case, since it has no name - is wrapped in parentheses and is thus treated by JavaScript as a function expression and not a function declaration. The (4) immediately following is an invocation of the function: we execute the function (that's the "Immediately-Invoked" bit) and pass in the value 4 for the parameter bar.

A Immediately-Invoked Function Expression (IIFE, often pronounced "iffy") without any parameters would look like this:

(function() {
	// body of function here
})();

where, as above, the () at bottom is an invocation of the function.

We can use IFFEs to create closures, since the function expressions are invoked immediately and properties inside of them are scoped to the expression.

We'll look next at two examples where we add click handlers to a page. In the first example (without an IIFE closure) the code doesn't work as intended; in the second example we fix the problem using an IIFE closure.

Code Sample:

AdvancedFunctions/Demos/divClick1.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Div Click 1</title>
	<style>
		div {
			width:100px;
			height:100px;
			float:left;
			margin-right:10px;
			border:1px solid #ff7800;
			background:#eee;
			text-align: center;
			font-size:28px;
			line-height: 100px;
		}
	</style>
	<script>
		window.onload = function() {
			var divs = document.getElementsByTagName('div');
			for (var i=0; i<divs.length; i++) {
				divs[i].addEventListener('click', function(e) {
					e.preventDefault();
					alert('you clicked div ' + i);
				}, 'false');
			}
		}
	</script>
</head>
<body>
	<h1>Div Click 1</h1>
	<div>0</div>
	<div>1</div>
	<div>2</div>
	<div>3</div>
	<div>4</div>
	<div>5</div>
</body>
</html>

Code Explanation

In divClick1.html, we add six divs to the page, styled to line up horizontally as squares and numbered 0 through 5.

On the event of window.load, we get all of the divs on the page, use a for loop to iterate over the collection of divs, and add a click handler which alerts the message 'you clicked div ' + i.

But, when we try out our page in a browser, it doesn't work as we had hoped: clicking any div results in an alert with the message you clicked div 6. The reason is that, by the time that any div is clicked, the value of parameter i is 6 (following the last iteration of the for loop).

We can fix this by using an IFFE to create a closure:

Code Sample:

AdvancedFunctions/Demos/divClick2.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Div Click 2</title>
	<style>
		div {
			width:100px;
			height:100px;
			float:left;
			margin-right:10px;
			border:1px solid #ff7800;
			background:#eee;
			text-align: center;
			font-size:28px;
			line-height: 100px;
		}
	</style>
	<script>
		window.onload = function() {
			var divs = document.getElementsByTagName('div');
			for (var i=0; i<divs.length; i++ ) {
				(function(i) {
					divs[i].addEventListener('click', function(e) {
						e.preventDefault();
						alert('you clicked div ' + i);
					}, 'false');
				})(i);
			}
		}
	</script>
</head>
<body>
	<h1>Div Click 2</h1>
	<div>0</div>
	<div>1</div>
	<div>2</div>
	<div>3</div>
	<div>4</div>
	<div>5</div>
</body>
</html>

Code Explanation

In divClick2.html, we again add six divs to the page and use a for loop to add a click handler to each one.

This time, however, we use an IFFE to create a closure when we create the click handler for each div. The function expression "remembers" the value of i at the time it is invoked, and thus clicks on any div correctly alert the message you clicked div 0, you clicked div 1, etc.

Next