One of the books that has most influenced my life is The Elements of Style by Strunk and White. I took a technical writing class in college where we closely studied its recommendations. The book is short and contains over 100 side-by-side comparisons of less effective and more effective writing.
Reading it made me realize that I learn well by example and comparison. I’ve long wanted to write an article that shows less effective and more effective programming approaches by comparison for those who also learn well by comparison.
Today I’m going to lay out what I’ve found to be the most important principles for writing clean code. In the first section, the examples are written in JavaScript, but they apply to almost every language. In the second section, the examples are specific to React.
Before we start the side-by-side comparisons, I want to make a recommendation that needs no side-by-side view.
Use prettier
If you have not heard of it, prettier is an automated code formatting tool. The idea is that you add a prettier config file to your project, and request all your teammates or contributors to enable an IDE plugin that re-formats code on save.
Never again will my team have an argument about tabs vs spaces or 80-column wrap vs 120-column wrap. It will also settle disputes about what types of quotes to use, whether to use semicolons or what spacing to use around brackets.
Prettier was created for JavaScript, JSX, and JSON, but it has plugins for HTML, CSS, md, XML, YAML, toml, PHP, python, ruby, java, shell and many more
My favorite thing is that I concentrate on code and not on formatting. I can quickly add code without proper newlines or spacing and then watch prettier magically format the new code.
Let’s start
Each recommendation below has a very short description and a code example so you can compare more effective vs. less-effective approaches.
Exit early when possible
When writing a function, consider the negative outcomes that would allow you to exit early from the function. You’ll find your code has fewer indentations and is easier to read.
Be expressive, not clever
Of the two functions below, which would you rather come across in a project? Maybe the first one is clever and concise, but how much time does it take you to tweak the functionality?
Make variable names descriptive
When you write code, you may have only one thing on your mind. But when you come back later to look at code, descriptive variable names are very helpful.
Prefer for-of loops
for-of
loops have some advantages over for-i
, forEach
and for-in
loops:
- Fewer characters
- Ability to continue, return or break from the loop
- Easier to read and follow
Prefix booleans with verbs such as “is” and “has”
Verbs help set a boolean apart from other types.
Avoid double negatives.
Sometimes they’re subtle and lead to cheeky bugs.
Avoid using “!” with “else”
Instead, use the positive form in the if
condition.
Prefer string interpolation over concatenation
It’s almost always more readable to interpolate.
Avoid using the ternary operator to a return boolean value
In return statements, ternary operators are redundant.
Use try-catch with await
async await
makes code more readable than a tree of .then()
calls. But don’t forget that you need to catch rejections that await
-ed values might throw.
Avoid using “magic” numbers
Any number or string that has a non-obvious meaning should be declared as a separate, descriptively named variable.
Avoid declaring functions with more than 2 arguments
Arguments should have a logical order. When you have 3 or more arguments, the order is often not obvious. Yes, we have intellisense in our IDE, but save some thought cycles by accepting “named” arguments if appropriate.
Prefer objects to boolean arguments
Code that calls the function will be cleaner and more obvious.
A Section on React
JSX and React have their own challenges that deserve some extra attention.
Declare DOM only once per function
You can take one of three approaches to avoid it:
- Break components into smaller units
- Use
&&
as a stand-in forif
blocks - Use the ternary operator for
if-else
blocks
Make your own wrappers on top of UI libraries
Your project might rely on MUI or another UI library for all it’s components. But keeping your UI consistent can be challenging if you have to remember sizes, colors and variants. In the example below, the project wants to always use medium outlined buttons in MUI.
Mind the guard operator
In Javascript, &&
is the guard operator not a boolean operator; it returns the first operand that is truthy.
A final word
Writing clean code takes practice. Be a code craftsman and take the time to learn good principles and make good habits.