Skip to main content Accessibility Feedback

The early return pattern in JavaScript

Today, I wanted to talk about one of my favorite tricks for making code a bit more readable: the early return pattern.

Let’s dig in!

The challenge with if checks

When coding, you often want to check if a condition exists before continuing.

For example, let’s say you have a function that runs whenever the user clicks a button with the .save-data class. It gets the value of the [data-id] attribute from the button, gets a saved token from localStorage, and then combines the two and saves it as a new entry in localStorage.

Along the way, you’ll want to make various checks to make sure that each piece of information you need exists before moving on.

function handleClick (event) {

	// Make sure clicked element has the .save-data class
	if (event.target.matches('.save-data')) {

		// Get the value of the [data-id] attribute
		let id = event.target.getAttribute('data-id');

		// Make sure there's an ID
		if (id) {

			// Get the user token from localStorage
			let token = localStorage.getItem('token');

			// Make sure there's a token
			if (token) {

				// Save the ID to localStorage
				localStorage.setItem(`${token}_${id}`, true);

			}

		}

	}

}

As you can see, this results in a nested mess of if checks. You could combine a few of these steps, but it’s not uncommon to see code like this “in the wild.”

The early return pattern solves this issue.

What is the early return pattern?

With the early return pattern, you check for the opposite of the thing you want, and return early to end the function when that’s the case.

This reduces nested if statements, and makes your code a bit easier to read.

Want to make sure the event.target has the .save-data class? Check if it doesn’t instead, and return when that’s the case. Same with the [data-id] attribute, or a token key in localStorage.

function handleClick (event) {

	// Make sure clicked element has the .save-data class
	if (!event.target.matches('.save-data')) return;

	// Get the value of the [data-id] attribute
	let id = event.target.getAttribute('data-id');

	// Make sure there's an ID
	if (!id) return;

	// Get the user token from localStorage
	let token = localStorage.getItem('token');

	// Make sure there's a token
	if (!token) return;

	// Save the ID to localStorage
	localStorage.setItem(`${token}_${id}`, true);

}

You can make this a bit more compact and readable by removing the “make sure there’s…” comments, too.

function handleClick (event) {

	// Make sure clicked element has the .save-data class
	if (!event.target.matches('.save-data')) return;

	// Get the value of the [data-id] attribute
	let id = event.target.getAttribute('data-id');
	if (!id) return;

	// Get the user token from localStorage
	let token = localStorage.getItem('token');
	if (!token) return;

	// Save the ID to localStorage
	localStorage.setItem(`${token}_${id}`, true);

}

That’s the early return pattern, my favorite pattern in JavaScript.