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 .flatMap(…)
over .map(…).flat()
We use flatMap
over map
and flat
together since we can do both things with flatMap
,
for instance,e instead of writing:
[1, 2, 3].map(i => [i]).flat();
We write:
[1, 2, 3].flatMap(i => [i]);
Use .includes()
Instead of .indexOf()
When Checking for Existence or Non-Existence
includes
is better than indexOf
when checking for existence or nonexistence.
includes
is shorter.
So instead of writing:
[].indexOf('foo') !== -1;
We write:
[].includes('foo');
Use Modern DOM APIs
We should use newer DOM methods than older ones.
For instance, instead of writing:
foo.replaceChild(baz, bar);
foo.insertBefore(baz, bar);
foo.insertAdjacentText('position', bar);
foo.insertAdjacentElement('position', bar);
We write:
foo.replaceWith(bar);
foo.before(bar);
foo.prepend(bar);
foo.append(bar);
Use Negative Index over .length - index
for slice and splice
Negative indexes are shorter than length — index
for slice
and splice
.
For instance, instead of writing:
foo.slice(foo.length - 3, foo.length - 1);
foo.splice(foo.length - 1, 1);
We write:
foo.slice(-3, -1);
foo.splice(-1, 1);
It’s much shorter and easier on our brains.
Use Node#append()
Over Node#appendChild()
We should use append
over appendChild
for appending elements to a parent,.
append
lets us append strings in addition to nodes.
append
has a node return value.
And we can append several nodes and strings with it.
For instance, instead of writing:
foo.appendChild(bar);
We write:
foo.append(bar);
foo.append(bar, 'baz');
Use childNode.remove()
over parentNode.removeChild(childNode)
We can use remove
to remove a node directly instead of getting the parent and call removeChild
to remove a node.
For instance, instead of writing:
parentNode.removeChild(foo);
We write:
foo.remove();
Use Number
Static Properties Over Global Ones
The number static properties are better than the global ones.
Number.isNaN
and Number.isFinite
don’t convert the type of the argument before doing the check.
For instance, instead of writing:
const foo = parseInt('20', 2);
const foo = parseFloat('30.5');
const foo = isNaN(20);
const foo = isFinite(20);
if (Object.is(foo, NaN)) {}
We write:”
const foo = Number.parseInt('20', 2);
const foo = Number.parseFloat('30.5');
const foo = Number.isNaN(20);
const foo = Number.isFinite(20);
if (Object.is(foo, Number.NaN)) {}
Use catch
Binding Parameter
If catch
‘s binding parameter isn’t used, then it should be omitted.
So instead of writing:
try {} catch (error) {}
We write:
try {} catch {}
Use .querySelector()
Over .getElementById()
, .querySelectorAll()
Over .getElementsByClassName()
and .getElementsByTagName()
querySelector
is more versatile than getElementById
since the former can take any selector.
querySelectorAll
is more versatile than getElementsByClassName
and getElementsByTagName
since it takes any selector.
So instead of writing:
document.getElementById('baz');
document.getElementsByClassName('baz bar');
document.getElementsByTagName('main');
We write:
document.querySelector('main #baz .bar');
document.querySelectorAll('.baz .bar');
Use Reflect.apply()
over Function#apply()
Reflect.apply
is shorter and easier to understand than Function.apply
.
And we know that it can never be overridden unlike Function.apply
.
So instead of writing:
function foo() {}
foo.apply(null, [42]);
We write:
function foo() {}
Reflect.apply(foo, null, [42]);
Use String#replaceAll()
Over Regex Searches with the Global Flag
replaceAll
is easier to understand than regex search and replace to replace substrings.
For instance, instead of writing:
string.replace(/foo/g, '');
We write:
string.replaceAll('foo', '');
Use Set#has()
Over Array#includes()
when Checking for Existence or Non-existence
We can use has
instead of includes
to check for existence or nonexistence since it’s faster.
For instance, instead of writing:
const array = [1, 2, 3, 4, 5];
const hasValue = value => array.includes(value);
We write:
const set = new Set([1, 2, 3, 4, 5]);
const hasValue = value => set.has(value);
Use the Spread Operator Over Array.from()
We should use the spread operator over Array.from
.
It’s a shorter way to turn array-like objects to arrays.
For instance, instead of writing:
Array.from(set).filter(() => {});
We write:
[...set].filter(() => {});
Use String#startsWith()
& String#endsWith()
to Check for Start and End of Strings
We should use startsWith
or endsWith
to check that a string starts or ends with a given string.
For instance, instead of writing:
/^bar/.test(foo);
/bar$/.test(foo);
We write:
foo.startsWith('bar');
foo.endsWith('bar');
Conclusion
We should use modern JavaScript methods to make our lives easier.
There are many strings and array methods to make our lives much easier.
We should also take note of new DOM method and use those instead of what’s available before.