To make code easy to read and maintain, we should follow some best practices.
In this article, we’ll look at some best practices we should follow to make everyone’s lives easier.
No Commented Out Code in our Codebase
We shouldn’t have commented out code in our codebase.
We have version control to keep a record of our changes.
So we should remove them.
If we have:
doStuff();
// doMoreStuff();
Then we should rewrite it to:
doStuff();
No Journal Comments
We shouldn’t have journal comments since version control has the code change records.
For instance, we shouldn’t write:
/**
* 2019-02-03: Removed type-checking
* 2018-03-14: Added add function
*/
function add(a, b) {
return a + b;
}
We write:
function add(a, b) {
return a + b;
}
No Positional Markers
Positional markers are just noise, we shouldn’t have them in our code.
Instead of writing:
////////////////////////////////////////////////////////////////////////////////
// initialize setup data
////////////////////////////////////////////////////////////////////////////////
const init = function() {
// ...
};
We write:
const init = function() {
// ...
};
Maximum Number of Classes Per File
We may want to enforce a maximum number of classes per file to reduce a file’s complexity and responsibility.
For instance, we may limit the number of classes to 3 max:
class Foo {}
class Bar {}
class Baz {}
Maximum Depth that Blocks can be Nested
Nested code is hard to read.
Therefore, we should eliminate them as much as possible.
One or 2 levels of nesting are probably the max that can be tolerated.
For instance, don’t write
function foo() {
for (;;) {
while (true) {
if (true) {
if (true) {
}
}
}
}
}
Instead, we write:
function foo() {
for (;;) {
}
}
We can use guard clauses to return early.
For instance, we can write:
function foo() {
if (!cond) {
return;
}
while (true) {
}
}
instead of:
function foo() {
if (!cond) {
while (true) {
}
}
}
We can also use break
or continue
to stop a loop or move to the next iteration of it.
Maximum Line Length
We’ve to scroll horizontally to read long lines.
Therefore, we shouldn’t write them.
For instance, we shouldn’t write:
const foo = { "foo": "This is a foo.", "bar": { "qux": "This is a bar"}, "baz": "This is a baz" };
It overflows the line.
Instead, we write:
const foo = {
"foo": "This is a foo.",
"bar": {
"qux": "This is a bar"
},
"baz": "This is a baz"
};
Each line is much shorter and easier to read.
We can do the same with comments.
Maximum File Length
Big files are complex and hard to understand.
Therefore, we should divide them into smaller files.
300 to 500 lines max is usually the recommendation.
Maximum Function Length
We should make sure our function only does one thing.
Therefore, we should reduce the length of our functions.
For instance, we can write:
function foo() {
let x = 0;
}
which is a short, simple function.
Maximum Depth that Callbacks can be Nested
We often have to run callbacks for both synchronous and async code.
We’ve to run many of them to do all the things we want.
The worst way to write them is to nest them deeply.
So we shouldn’t write things like:
foo(function() {
bar(function() {
qux(function() {
abc(function() {
});
});
});
});
That’s just very hard to read and debug, especially if we have lots of code in each callback.
We should use alternatives like promises.
Maximum Number of Parameters in Function Definitions
We shouldn’t have too many parameters in a function.
The more we have, the harder it is to read.
For instance, instead of writing:
function foo(bar, baz, qux, abc) {
doSomething();
}
We write:
function foo({ bar, baz, qux, abc }) {
doSomething();
}
If we need lots of parameters, we can take an object and destructure them.
Conclusion
We shouldn’t have commented out code or other useless comments.
Nesting, function length, and the number of parameters should be minimized.
The number of classes should also be reduced.
A file shouldn’t have too many lines of code.