The Art of Code Refactoring in JavaScript: Techniques for Improving Code Quality

London Lingo
5 min readMay 11, 2023

--

Image by Freepik

Code refactoring is the process of restructuring existing code without changing its external behavior. It’s an essential part of software development that can improve code quality, readability, and maintainability. In this post, we’ll explore some techniques for refactoring JavaScript code.

Why Refactor Code?

Refactoring code can have several benefits. It can make code easier to read and understand, which can reduce the time it takes to make changes or fix bugs. It can also improve the performance of the code and make it more reusable.

Techniques for Refactoring JavaScript Code

There are several techniques that you can use to refactor JavaScript code. Here are a few common ones:

1. Extracting Functions

One of the most common techniques for refactoring code is to extract functions. This involves taking a piece of code that performs a specific task and moving it into its own function. This can make the code more readable and reusable.

Here’s an example:

// Before refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
totalPrice += items[i].price * items[i].quantity;
}
return totalPrice;
}

// After refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
totalPrice += calculateItemTotal(items[i]);
}
return totalPrice;
}

function calculateItemTotal(item) {
return item.price * item.quantity;
}

In this example, we’ve extracted the code that calculates the total price of an item into its own function. This makes the calculateTotalPrice function easier to read and understand.

2. Removing Duplicate Code

Another common technique for refactoring code is to remove duplicate code. This involves identifying pieces of code that perform the same task and consolidating them into a single function.

Here’s an example:

// Before refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
if (items[i].discount) {
totalPrice += items[i].price * items[i].quantity * (1 - items[i].discount);
} else {
totalPrice += items[i].price * items[i].quantity;
}
}
return totalPrice;
}

// After refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
totalPrice += calculateItemTotal(items[i]);
}
return totalPrice;
}

function calculateItemTotal(item) {
if (item.discount) {
return item.price * item.quantity * (1 - item.discount);
} else {
return item.price * item.quantity;
}
}

In this example, we’ve removed the duplicate code that calculates the total price of an item by moving it into its own function. This makes the calculateTotalPrice function easier to read and understand.

3. Renaming Variables and Functions

Renaming variables and functions is another technique for refactoring code. This involves changing the names of variables and functions to make them more descriptive and easier to understand.

Here’s an example:

// Before refactoring
function calcTotPrice(items) {
let totPrice = 0;
for (let i = 0; i < items.length; i++) {
totPrice += calcItemTot(items[i]);
}
return totPrice;
}

function calcItemTot(item) {
return item.price * item.quantity;
}

// After refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
totalPrice += calculateItemTotal(items[i]);
}
return totalPrice;
}

function calculateItemTotal(item) {
return item.price * item.quantity;
}

In this example, we’ve renamed the calcTotPrice and calcItemTot functions to calculateTotalPrice and calculateItemTotal, respectively. We’ve also renamed the totPrice variable to totalPrice. These changes make the code easier to read and understand.

4. Simplifying Conditional Expressions

Simplifying conditional expressions is another technique for refactoring code. This involves rewriting conditional expressions to make them easier to read and understand.

Here’s an example:

// Before refactoring
function isEligibleForDiscount(item) {
if (item.price > 100 && item.quantity > 2) {
return true;
} else {
return false;
}
}

// After refactoring
function isEligibleForDiscount(item) {
return item.price > 100 && item.quantity > 2;
}

In this example, we’ve simplified the isEligibleForDiscount function by removing the unnecessary if statement and returning the result of the conditional expression directly.

5. Replacing Loops with Functional Programming Constructs

Replacing loops with functional programming constructs is another technique for refactoring code. This involves using functions such as map, filter, and reduce to perform operations on arrays instead of using loops.

Here’s an example:

// Before refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
totalPrice += calculateItemTotal(items[i]);
}
return totalPrice;
}

// After refactoring
function calculateTotalPrice(items) {
return items.reduce((totalPrice, item) => totalPrice + calculateItemTotal(item), 0);
}

In this example, we’ve replaced the for loop in the calculateTotalPrice function with a call to the reduce function. This makes the code more concise and easier to read.

6. Encapsulating Conditionals

Encapsulating conditionals is a technique for refactoring code that involves moving complex conditional logic into its own function. This can make the code easier to read and understand.

Here’s an example:

// Before refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
if (items[i].price > 100 && items[i].quantity > 2) {
totalPrice += calculateItemTotal(items[i]) * 0.9;
} else {
totalPrice += calculateItemTotal(items[i]);
}
}
return totalPrice;
}

// After refactoring
function calculateTotalPrice(items) {
let totalPrice = 0;
for (let i = 0; i < items.length; i++) {
if (isEligibleForDiscount(items[i])) {
totalPrice += calculateItemTotal(items[i]) * 0.9;
} else {
totalPrice += calculateItemTotal(items[i]);
}
}
return totalPrice;
}

function isEligibleForDiscount(item) {
return item.price > 100 && item.quantity > 2;
}

In this example, we’ve encapsulated the conditional logic for determining whether an item is eligible for a discount into its own function. This makes the calculateTotalPrice function easier to read and understand.

7. Replacing Temp with Query

Replacing temp with query is a technique for refactoring code that involves replacing temporary variables with function calls. This can make the code more readable and reduce the number of variables that need to be tracked.

Here’s an example:

// Before refactoring
function calculateTotalPrice(items) {
let basePrice = calculateBasePrice(items);
let discount = calculateDiscount(basePrice);
return basePrice - discount;
}

function calculateBasePrice(items) {
let basePrice = 0;
for (let i = 0; i < items.length; i++) {
basePrice += calculateItemTotal(items[i]);
}
return basePrice;
}

function calculateDiscount(basePrice) {
if (basePrice > 1000) {
return basePrice * 0.1;
} else {
return 0;
}
}

// After refactoring
function calculateTotalPrice(items) {
return calculateBasePrice(items) - calculateDiscount(calculateBasePrice(items));
}

function calculateBasePrice(items) {
return items.reduce((basePrice, item) => basePrice + calculateItemTotal(item), 0);
}

function calculateDiscount(basePrice) {
if (basePrice > 1000) {
return basePrice * 0.1;
} else {
return 0;
}
}

In this example, we’ve replaced the basePrice and discount temporary variables with calls to the calculateBasePrice and calculateDiscount functions, respectively. This makes the calculateTotalPrice function more concise and easier to read.

Code refactoring is an essential part of software development that can improve code quality, readability, and maintainability. By using techniques such as extracting functions, removing duplicate code, renaming variables and functions, simplifying conditional expressions, replacing loops with functional programming constructs, encapsulating conditionals, and replacing temp with query, you can make your JavaScript code more readable and reusable.

Thank you for taking the time to read this blog post. We hope that it has provided you with some useful insights into the art of code refactoring in JavaScript. Remember that refactoring is an ongoing process and that there are always opportunities to improve the quality of your code. Happy coding!

--

--