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 Unnecessary Boolean Casts
We shouldn’t have duplicate boolean casts.
For instance, we shouldn’t have code like:
const foo = !!!bar;
const foo = !!bar ? baz : bat;
const foo = Boolean(!!bar);
const foo = new Boolean(!!bar);
if (!!foo) {
// ...
}
if (Boolean(foo)) {
// ...
}
while (!!foo) {
// ...
}
Instead, we write:
const foo = !bar;
const foo = bar ? baz : bat;
const foo = Boolean(bar);
const foo = new Boolean(bar);
if (foo) {
// ...
}
if (foo) {
// ...
}
while (foo) {
// ...
}
We remove all the extra Boolean
or !
calls and operators since we don’t need them.
No Unnecessary Labels
We can put labels to label loops.
But most of the time, we don’t need them.
It’s also a rarely used feature.
So many people will be confused.
For instance, instead of writing:
A: while (a) {
break A;
}
We write:
while (a) {
break;
}
No Unnecessary Parentheses
We should have parentheses in places where they’re unnecessary.
For instance, instead of writing:
a = (b * c);
(a * b) + c;
for (a in (b));
for (a of (b));
typeof (a);
We write:
a = b * c;
a * b + c;
for (a in b);
for (a of b);
typeof a;
This saves us typing and space.
No Unnecessary Semicolons
We shouldn’t add unnecessary semicolons.
For instance, instead of writing:
const x = 5;;
We write:
const x = 5;
We also don’t need semicolons after function declarations:
function foo() {
//...
};
We can just write:
function foo() {
//...
}
No Case Statement Fallthrough
Remember to add break
in case
statements.
For instance, we shouldn’t write:
switch (foo) {
case 1:
doSomething();
case 2:
doSomethingElse();
}
Instead, we write:
switch (foo) {
case 1:
doSomething();
break;
case 2:
doSomethingElse();
break;
}
No Floating Decimals
Floating decimals are confusing for some people.
We can write a decimal in place of 0.
For instance,
const num = .5;
sets num
to 0.5.
We should just put the leading zero in our number:
const num = 0.5;
No Reassigning Function
Declarations
We shouldn’t reassign function declarations to something.
If we do, it’ll cause confusion.
For instance, instead of writing:
function foo() {}
foo = bar;
We write:
function foo() {}
const bar = 1;
No Assignment to Native Objects or Read-Only Global Variables
We shouldn’t assign anything to native objects or read-only global variables.
For instance, we shouldn’t have code like:
window = {};
`Object = undefined;
undefined = 1;`
Instead, we assign them to our own variables:
const a = {};
const b = undefined;
const c = 1;
Type Conversion with Shorter Notations
Some shorter notations can be used.
For instance, we can write:
const num = +'123';
to convert num
to a number.
We can also use !!
to convert to a boolean:
const b = !!foo;
Others like concatenating to a string or using bitwise operators are more confusing and probably should be avoided.
No Declarations in the Global Scope
We shouldn’t declare global variables.
It’s easy to have scope clashes and it’s hard to trace where they came from.
For instance, we shouldn’t have code like:
var foo = 1;
bar = 2;
function baz() {}
Instead, we write:
let foo = 1;
const bar = 2;
let baz = () => {}
We keep them block-scoped to prevent accidental access.
No Implied eval()
setTimeout
and setInterval
can take a string instead of a callback to run code.
It’s like eval
. The code is dangerous and prevents optimizations since the code is in a string.
So instead of writing:
setTimeout("alert('hello');", 100);
setInterval("alert('hello');", 100);
We write:
setTimeout(function() {
alert("hello");
}, 100);
setInterval(function() {
alert("hello");
}, 100);
Conclusion
We should always pass in a callback instead of a string to setTimeout
and setInterval
.
Also, we shouldn’t case booleans unnecessarily.
Useless labels and parentheses should also be removed.
And we should never create global variables or assign things to built-in objects.