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.
Use String#slice()
Instead of String#substr()
and String#substring()
The slice
method can do what the substr
or substring
method does except it’s shorter.
It’s also more consistent with arrays.
For instance, instead of writing:
foo.substr(start, end);
foo.substring(start, end);
We write:
foo.slice(start, end);
Use .textContent
over .innerText
textContent
is faster and more predictable than innerText
, so we should use that instead.
textContent
can also have CDATA and processing instructions.
It’ll also concatenate the textContent
of all the nodes.
So instead of writing:
foo.innerText = 'foo';
We write:
foo.textContent = 'foo';
Use String#trimStart()
/ String#trimEnd()
Instead of String#trimLeft()
/ String#trimRight()
trimStart
and trimEnd
are more consistent with the other methods like padStart
or padEnd
.
trimStart
trims the whitespace from the start of a string.
And trimEnd
trims the whitespace from the end of the string.
So we should use trimStart
or trimEnd
For instance, instead of writing:
str.trimLeft();
str.`trimRight`();
We write:
str.trimStart();
str.`trimEnd`();
Throwing TypeError
in Type Checking Conditions
If we may get data wit invalid data types, then we may want to throw type errors to make them very obvious.
For instance, instead of writing:
if (!Array.isArray(bar)) {
throw new Error('not an array');
}
We write:
if (!Array.isArray(bar)) {
throw new TypeError('not an array');
}
TypeError
is specifically thrown when data types don’t match.
No Abbreviations
If the full names aren’t too long, then we shouldn’t abbreviate them.
For instance, insteaf of writing:
class Btn {}
We write:
class Button {}
And instead of writing:
const err = new Error();
We write:
const err = new Error();
Use new
When Throwing an Error
Error
is a constructor, so we should invoke it with new
.
For instance, instead of writing:
throw Error();
We write:
throw new Error();
Use isNaN()
to Check for NaN
isNaN
is a function that’s specifically made to check for NaN
.
We need this since we can’t use ===
or !==
to check it.
For instance:
if (bar === NaN) {
// ...
}
won’t work since NaN
doesn’t equal itself.
Instead, we write:
if (isNaN(bar)) {
// ...
}
to do the correct comparison.
Other comparison operators also don’t work like we expect with NaN
.
Compare typeof
Expressions Against Valid Strings
The typeof
operator returns a string with the data type name, so we should be comparing against strings.
For instance, instead of writing things like
typeof bar === "strnig"
typeof bar === "undefibed"
We write:
typeof bar === "string"
typeof bar === "undefined"
Variable Declarations to be at the Top of Their Scope
We can put variable declarations at the top of their scope so w can find them more easily.
For instance, instead of writing:
function doWork() {
var foo;
if (true) {
foo = 'abc';
}
var bar;
}
We write:
function doWork() {
var foo;
var bar;
if (true) {
foo = 'abc';
}
}
so that we can find them all in one place.
IIFEs should be Wrapped
We need to wrap IIFEs to make the JavaScript interpreter parse it as an expression rather than a declaration.
For instance, instead of writing:
let z = function() {
return {
y: 'abc'
};
}();
We write:
let z = (function() {
return {
y: 'abc'
};
})();
The 2nd example will be declared as an expression.
Regex Literals should be Wrapped
We may wrap regex literals to make them easier to read.
For instance, instead of writing:
/baz/.test("bar");
We write:
(/baz/).test("bar");
Spacing Around the *
in yield*
Expressions
We usually don’t put a space between yield
and *
whem we call generator functions within another generator function.
So instead of writing:
function* generator() {
yield * foo();
}
We write:
function* generator() {
yield* foo();
}
Conclusion
We should use slice
rather than substr
or substring
.
Also, we should use trimStart
and trimEnd
so that it’s consistent with padStart
or padEnd
.
When we encounter types that we don’t expect, we should throw TypeError
s instead of generic errors.