Writing clean code improves the maintainability of the application and make developers productive. However, some developers are unaware of the language features available to further enhance the code.
Why Clean Code is Important
As a beginner, your focus is not necessarily on writing clean code. Your focus should be on getting the code working and your tests passing. As you become more experienced you can start focusing on writing clean code.
In this article, I define clean code as:
- Easy to read
- Easy to understand
Clean code will help you get up-to-speed with and maintain a codebase. It’s always worth the effort of making your code cleaner, even if it takes a longer time to write!
1. Use a linter (ESLint)
2. Isolate your code
The most crucial thing I can suggest to keep a codebase organized and understandable is to divide specific logic chunks (often functions) into different topics. If you create a function, it should by default serve just one purpose and not carry out many tasks simultaneously.
Also, you should avoid causing side effects, meaning in most cases, you should not change anything that is declared outside your function. You receive data into functions with parameters; everything else should not be accessed. If you wish to get something out of the function,
return new values.
3. Use a try catch on all api requests & JSON methods
When requesting data from an API, a lot of things can go wrong, thus it’s imperative to consider these possibilities. Don’t automatically believe what you are told when handling JSON; instead, attempt to make your code more resilient by managing potential discrepancies.
4. Use Multiple Parameters Over Single Object Parameter
When declaring a function, we should always use multiple input parameters instead of single object inputs. This approach helps developers easily understand the minimum number of parameters that need to be passed by looking at the method signature.
Also, it improves the application performance since there is no need to create object parameters or collect garbage.
However, if the number of input parameters increase, you should switch back to using object parameters to avoid unnecessary code complexities.
Note: If you use TypeScript and have number of parameters, its easier to define the interface of the parameters to benefit from type checking and auto-suggestions.
5. Utilise template strings
Template strings will allow you to inject values into the string while preserving the format and the code is much more reader friendly than doing string arithmetic.
6. Avoid Hard-coded values
This is an issue that I often request changes for the Pull Requests I review. And is a no-go. Let’s see an example:
The meaning of this figure, how it was calculated, and the business rationale behind it would all be unknown to someone glancing at the code. We could’ve made the following constant in its place rather than hardcoding this value:
7. Prefer multiple parameters over single object parameters
When declaring a function, you should always prefer multiple parameters over one parameter that expects an object:
The reason behind this is that you know exactly what you need to pass to the function when you look at the first line of the function declaration.
Although functions should only be capable of doing one task, it is possible for them to expand in size. It will take more time to search through the body of the function for the variables you need to pass—variables that are nested inside an object. Even while it could often appear simpler to use the entire object and give it to the method, this configuration will help your application scale.
There is a certain point where declaring specific parameters does not make sense. For me, it is above four or five function parameters. If your function grows that big, you should pivot to use object parameters.
The main reason here is that parameters need to be passed in a specific order. If you have optional parameters, you need to pass
null. With object parameters, you can simply pass the whole object, where order and
undefined values do not matter.
8. Utilise regex when needing to search strings
9. Utilise optional chainings
Stop having long logical conjunctions and simplify your code with optional chaining.
10. Make Use of Arrow Functions
this property inside callbacks.
If you are using arrow functions, curly braces, parenthesis, function, and return keywords become optional. Most importantly, your code becomes more understandable and clearer.
The below example shows a comparison between a single-line arrow function without parentheses and a regular function.
Although arrow functions are much simpler, we must understand when and how to use them.
For example, using arrow functions is not the best approach when working with object prototypes, classes, or object literals.
Also, arrow functions cannot be used as function constructors. You will receive an error if you use the new keyword to create a new object from an arrow function.
11. Avoid nesting
Nesting is a certain technique to make your code more complex and difficult to read and understand. If it has more than two levels, think about reworking by using root level return conditions, shorter blocks, and abstracting nested logic to separate functions.
12. Use Template Literals for String Concatenations
Template literals are literals delimited with backticks (
`). It provides an easy way to create multiline strings and perform string interpolation.
For example, we can define a placeholder in a string to get rid of all unnecessary concatenations.
13. Data scarcity
The previous advice points us in one direction: don’t distribute information you don’t need. Once again, while configuring your functions, it can entail a little extra work. However, over time, it will unquestionably result in a better legible codebase for you. Knowing exactly which values are utilized where is quite helpful.
14. Use prettier
Working in a team requires a clear style guide and formatting. ESLint offers a huge ruleset that you can customize to your needs. There is also
eslint --fix, which corrects some of the errors, but not all.
Instead, I recommend using Prettier to format your code. That way, developers do not have to worry about code formatting, but simply writing high-quality code. The appearance will be consistent and the formatting automatic.
15. Comment all atypical code, but don’t let it replace code readability
You may occasionally have to deal with unusual situations for which there aren’t set rules. It will be extremely helpful to other programmers and a reminder to yourself when you return to the code in the future if you comment this code to help clarify what it does and the context that is being taken into account. However, this must not be used as an excuse for not taking proper care to write legible code in the first place.
As developers, we should always write clean code since it increases readability and makes it easier for you and your team to understand the code.
I wish that these tips will assist you in making your code more readable. If you have any more advice, please leave it in the comments section for other readers to see.
Thank you for reading!