3 JavaScript Refactoring Techniques for Cleaner Code

Sharpen your coding skills with these 3 key JavaScript refactoring techniques. Follow best practices for writing cleaner, more maintainable code.

#javascript
#refactoring
#bestpractices

I’m convinced every developer should always be proud of his code. I think it’s impressive what people in our community can do in terms of technological development. But it is even more important to be humble and remember there’s always room for improvement.

I realized this during my studies at Codeworks, a JavaScript coding Bootcamp where I had the chance to meet incredible developers.

One of them recommended a book, Refactoring by Martin Fowler, a collection of refactoring techniques to improve the design and readability of your code.

It completely changed the perspective I had on my code, helping me to translate it for humans and not machines anymore.

That’s why I’d like to share three of the most useful refactoring techniques you can apply to your code.

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Martin Fowler

Extract Function

js
/**
* Before
*/
function printMenu(menu) {
// Print menu name
console.log('******');
console.log('Menu: ', menu.name);
console.log('******');

// Print menu dishes
console.log(menu.dishes[0]);
console.log(menu.dishes[1]);
}

/**
* After
*/
function printMenu(menu) {
printMenuName(menu.name);

// Print menu dishes
console.log(menu.dishes[0]);
console.log(menu.dishes[1]);

function printMenuName(name) {
console.log('******');
console.log('Menu: ', name);
console.log('******');
}
}

Reason

Often code gets difficult to understand, especially when we use less explicative syntax. Once we realize the code is not completely easy to read, extracting some code in a function helps to explain what that portion of the code does. When adding many responsibilities to the same function, we have already lost control over that part of the code.

Benefits

  • Shorter functions.
  • More explicative names to describe the code's purpose.
  • Less useless comments.

Implementation

  • Create a new function and name it for what it does.
  • Cut/paste the extracted code from the source code into the new function.
  • Pass as a parameter the possible variables in the new function scope from the source code.

Introduce Parameter Object

js
/**
* Before
*/
function locationAddress(latitude, longitude) {}
function locationCity(latitude, longitude) {}
function locationCountry(latitude, longitude) {}

/**
* After
*/
function locationAddress(coordinates) {}
function locationCity(coordinates) {}
function locationCountry(coordinates) {}

Reason

When handling data in a program, often some of them are used together in many functions and for different purposes. Grouping them into a structure such as an object makes explicit the relationship between the data items. But the real benefit of this refactoring is the flexibility it brings to a function.

Benefits

  • Compact argument into a structure.
  • Unordered and easy extensible list of arguments.

Implementation

  • Create a well-named structure that represents the behavior.
  • Replace the parameter list in the function declaration with the new structure.

Combine Functions into a Class

js
/**
* Before
*/
function calculateRanking(score) {}
function addExtraPoint(score) {}
function removePoint(score) {}

/**
* After
*/
class Score {
calculateRanking() {}
addExtraPoint() {}
removePoint() {}
}

Reason

When using a group of actions operating on a common entity, using a class makes more explicit what common environment these methods will share. It makes more readable code and encapsulates together functionalities by their behavior.

Benefits

  • Group together functions that work on the same dataset.
  • Increase code readability by making the action subject more explicit.
  • Provide a reference such as an object to pass to other parts of the system.

Implementation

  • Encapsulate in the class the shared data, passing it as a parameter into the class constructor.
  • Move all the associated functions into the class.
  • Each bit logic of logic working on the data can be extracted into a new function and moved into the class.

Last updated: