Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
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.
Having the Correct for Loop Direction
We should make sure that we update the index variable in the right direction so that we don't get infinite loops.
For instance, the following is probably wrong:
for (var i = 0; i < 10; i--) {
}
The loop never ends since i
is being decremented in each iteration.
Instead, we should write:
for (var i = 0; i < 10; i++) {
}
so that the i
variable gets to 10.
Return Statement should be Present in Property getters
If we define a getter, then we should return something.
Otherwise, the getter is useless.
For instance, instead of writing:
const obj = {
get name() {
}
};
We write:
const obj = {
get name() {
return 'james'
}
};
or:
Object.defineProperty(person, "age", {
get() {
return 17;
}
});
No async Function as a Promise Executor
We shouldn't have async
functions in our Promise
constructor.
This is because async
functions already returns promises, so it's redundant.
For instance, we shouldn't write;
const result = new Promise(async (resolve, reject) => {
resolve(await foo);
});
or:
const foo = new Promise(async (resolve, reject) => {
readFile('bar.txt', (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
It's completely redundant to have them.
Instead, we write:
const foo = new Promise((resolve, reject) => {
readFile('bar.txt', (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
or:
const result = Promise.resolve(1);
No await Inside Loops
We should move await
outside of promises that can run in parallel.
So instead of writing:
copnst foo = async (things) => {
const results = [];
for (const thing of things) {
results.push(await bar(thing));
}
return baz(results);
}
We write:
const foo = async (things) => {
const results = things.map(thing =>bar(thing));
return baz(await Promise.all(results));
}
We map the things
entries to promises.
Then we use Promise.all
to run all the promises in parallel.
No Comparison Against -0
Comparing against -0 won't work as intended.
Instead, we compare an expression with 0.
So instead of writing:
if (x === -0) {
//...
}
We write:
if (x === 0) {
//...
}
We can use Object.is
to compare against -0:
if (Object.is(x, -0)) {
// ...
}
Object.is
distinguishes between +0 and -0.
No Assignment Operators in Conditional Statements
Assinging things in operators is probably a mistake if we don't compare it against something.
For instance:
if (user.title = "employee") {
//...
}
isn't comparing user.title
to 'employee'
.
Instead, we write:
if (x === 0) {
b = 1;
}
to make sure we're comparing against an expression.
Remove console from Production Code
We shouldn't run console.log
when our code goes to production.
Therefore, we should remove them.
It's good for debugging but we should remove them before we check in our code.
Conclusion
We should take note of some basic best practices when writing JavaScript code.
Don't use async
and await
with the Promise
constructor.
Don't write infinite loops unintentionally.
And return things in getters.
Also, don't assign variables unintentionally in our if
statements.