Subscribe to my email list now at http://jauyeung.net/subscribe/
Follow me on Twitter at https://twitter.com/AuMayeung
Many more articles at https://medium.com/@hohanga
Even more articles at http://thewebdev.info/
Bad code has lots of unique characters. In this article, we’ll look at each one and what they are. We look at more general code smells.
Use Explanatory Variables
Variables should have names that explain themselves. For example, something that isn’t explanatory is something like x
or y
. We don’t know what they mean.
On the other hand, numOranges
or numApples
are explanatory since they tell us what we’re going to store in these variables. We know that we’re setting it to the number of oranges and apples respectively.
Function Names Should Say What They Do
Function names need to tell what they’re doing so we don’t have to guess.
For example, we don’t know what date.add(2)
does? It can be adding seconds, minutes, hours, days, months, or whatever we didn’t think of yet.
We should rename it to something more clear like addDays
or addMonths
so that we know what we’re adding.
If we have to look at the code or documentation to know what it does at a high level, then maybe it should be renamed.
Understand the Algorithm
We should understand the code that we write. Otherwise, we may hit a fluke once in a while, but if we don’t know what it’s doing exactly, then we’re going to run into problems eventually.
When we do run into problems, we won’t know how to resolve them since we didn’t understand what we wrote in the first place.
Also, writing code by guessing creates messy code as we’re messing with them to get them to work but we’re afraid that when we clean up the code, that it’ll fail again.
Therefore, we should think and understand before and during the time that we write our code.
Prefer Polymorphism to Conditionals
Conditionals are long messy. Nested ones are even worse. We should use them as little as possible if we’re just going to use them to invoke different objects.
Follow Standard Convention
Everyone should follow coding standards based on industry norms. In JavaScript, there’re conventions for naming variables, constants, and functions.
Also, the spacing and maximum line length are standardized across files.
We can deal with these automatically by using Linters and code formatters.
Other things like vertical formatting and function and variables placement have to be dealt with manually.
Replacing Magic Numbers with Named Constants
It’s hard to know what a number means when it’s not assigned to a constant.
Therefore, if we use a number as a constant, we should assign it to one so that we know what they mean.
For example, if we have a constant for hours per day, we should write:
const HOURS_PER_DAY = 24;
instead of just 24
.
Other issues include floating-point numbers that need precision. To keep the precision the same, we should assign them to a constant.
Something like PI
and E
should be assigned to constants so that they always have the same precision.
In addition to numbers, they also apply to any other constant values that are repeatedly used. For example, if we always write tests using the string 'Joe'
, then we can assign it to a constant and reference it everywhere.
This way, we avoid errors typing and reduce the chance of creating bugs.
Be Precise
We should be precise with everything in our code. For example, we shouldn’t use the word array
in our variable names unless it’s an array.
If we expect something to return null
or undefined
, then we should check for those.
Also, we should expect the first match of anything to be the correct match. We should actually check for the conditions that we’re looking for.
Structure over Convention
We should enforce structure over convention. We can shape the structure with tests and reviews.
Encapsulate Conditionals
When we have a conditional with multiple conditions, consider encapsulating them in a function.
For example, instead of writing:
if (employee.type === 'FULL_TIME' && employee.hasHealthBenefits) {
}
We can put the boolean expression into a function as follows:
const hasFullTimeHealthBenefits = (employee) => {
return employee.type === 'FULL_TIME' && employee.hasHealthBenefits;
}
if (hasFullTimeHealthBenefits(employee)) {
}
Avoid Negative Conditionals
Negatives are hard on our brains, so we should use positive boolean expressions whenever we can. For example:
if (isEmployed) {
}
is better than:
if (!isNotEmployed) {
}
Functions Should Do One Thing
Functions should do only one thing. If a function does multiple things, then we should split it into smaller functions.
For example, if we have the following code:
const calculateTotalPay = (employees) => {
let totalPay = 0;
for (let employee of employees) {
totalPay += employee.regularPay;
totalPay += employee.overtimePay;
totalPay += employee.bonus;
}
return totalPay;
}
We can instead move the totalPay
calculations to its own function as follows:
const calculateEmployeePay = (employee) => {
return employee.regularPay +
employee.overtimePay +
employee.bonus;
}
const calculateTotalPay = (employees) => {
let totalPay = 0;
for (let employee of employees) {
totalPay += calculateEmployeePay(employee);
}
return totalPay;
}
Now we have one function to get the total pay and employee’s pay instead of one big function to get both the employee’s pay and the total pay of all employees.
Conclusion
We should follow standard conventions when writing code. Names should be clear, they should also follow the same case.
Double negatives are also hard to understand, so we should avoid them.
We should assign any literal values to constants if they’re used repeatedly.
Finally, functions should only do one thing to make them simple.
The post JavaScript Clean Code — Functions and Convention Heuristics appeared first on The Web Dev.