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 Dangling Underscores in Identifiers
Dangling underscores are used for identifying private variables whether they’re actually private or not.
It’s best not to use this since if they’re not private, people may think it’s private.
So instead of writing:
foo._bar();
We write:
foo.bar();
No Confusing Multiline Expressions
We should separate statements and expressions with semicolons when they need to be separated.
For instance, we shouldn’t code like:
const foo = bar
[1, 2, 3].forEach(log);
We don’t know if the 2 lines should be together or not.
Instead, we write:
const foo = bar;
[1, 2, 3].forEach(log);
to separate them clearly.
No Unmodified Conditions of Loops
We shouldn’ have unmodified conditions in loops.
This creates infinite loops, which probably don’t want.
For instance, we shouldn’t write:
while (item) {
doWork(item);
}
Instead, we write:
for (let j = 0; j < items.length; j++) {
doWork(items[j]);
}
No Ternary Operators when Simpler Alternatives Exist
We shouldn’t use ternary expressions when there’re simpler alternatives.
For instance, we shouldn’t write:
const isOne = answer === 1 ? true : false;
Instead, we write:
const isOne = answer === 1;
We don’t need to write true
and false
explicitly.
No Unreachable Code After return
, throw
, continue
, and break
Statements
We shouldn’t have unreachable code after return
, throw
, continue
, and break
statements since they’ll never be run.
For instance, instead of writing:
function foo() {
return true;
console.log("end");
}
We write:
function foo() {
return true;
}
No Control Flow Statements in finally
Blocks
We shouldn’t have control flow statements like return
statements in finally
blocks.
Instead, we should put them elsewhere.
Control flow statements are suspended until finally
runs.
So the control flow statements in try
or catch
will be overwritten with the one in finally
.
Therefore, instead of writing:
try {
return 1;
} catch (err) {
return 2;
} finally {
return 3;
}
We write:
try {
return 1;
} catch (err) {
return 2;
} finally {
console.log('finally');
}
No Negating the Left Operand of relational Operators
We shouldn’t negate the left operand of relational operators since they only negate the operand and not the whole expression.
For instance, instead of writing:
if (!key in obj) {
// ...
}
We write:
if (!(key in obj)) {
// ...
}
No Unused Expressions
If an expression isn’t used, then we should remove them.
For instance, we shouldn’t write:
{0}
or:
c = a, b;
instead, we write:
f()
or:
a = 0
etc.
No Unused Variables
If we have unused variables, we should remove them.
So if we have:
var x;
and it isn’t used anywhere else, then we should remove them.
No Early Use of Variables and Functions
We shouldn’t use variables or functions before they’re declared in our code.
For instance, we can write:
console.log(a);
var a = 10;
or:
f();
function f() {}
We can use function declarations and variables before they’re declared.
Function declarations can be called, but variables will be undefined
if they’re used before they’re declared.
To remove confusion, we should write:
var a = 10;
console.log(a);
and:
function f() {}
f();
No Unnecessary .call()
and .apply()
We shouldn’t use call
and apply
unnecessarily.
If we don’t change the value of this
, then we shouldn’t use them.
Instead, we just call it directly.
So instead of writing:
foo.call(undefined, 1, 2, 3);
foo.apply(undefined, [1, 2, 3]);
obj.foo.call(obj, 1, 2, 3);
obj.foo.apply(obj, [1, 2, 3]);
We write:
foo(1, 2, 3)
obj.foo(1, 2, 3)
No Unnecessary catch Clauses
If our catch
clause only rethrows an exception, then we don’t need them.
So we shouldn’t write:
try {
doWork();
} catch (e) {
throw e;
}
try {
doWork();
} catch (e) {
throw e;
} finally {
cleanUp();
}
We write:
try {
doWork();
} catch (e) {
handleError(e);
}
try {
doWork();
} catch (e) {
handleError(e);
} finally {
cleanUp();
}
Conclusion
We shouldn’t write useless statements.
They make our code more complex and are redundant.