JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.
In this article, we’ll look at some redundant code that we should remove from our code that we may put in our async functions and other places.
No Unnecessary return await
In JavaScript, async functions always return promises. If we return something there, we return a promise with the resolved value being what we return in the promise.
return await
doesn’t do anything except adding extra time before the promise resolves or rejects.
Therefore, we can just return the promise directly.
The only valid use of return await
is in a try...catch
statement to catch errors from another function that returns a promise.
For instance, the following code is bad:
const foo = async () => {
return await Promise.resolve(1);
}
as we don’t need the await
to return the promise.
We can instead just write:
const foo = async () => {
return Promise.resolve(1);
}
However, the following use of return await
is good:
const foo = async () => {
try {
return await Promise.resolve(1);
} catch (ex) {
console.log(ex);
}
}
No Script URLs
Having javascript:
URL is a bad practice because it exposes us to the same performance and security issues as eval
.
They both let us run arbitrary code from a string, so attackers can do the same.
Also, the performance from running code from a string is slower since the JavaScript interpreter can’t optimize code that’s in a string.
For instance, we should write code like:
location.href = "javascript:alert('foo')";
Instead, just put it inside the JavaScript code as follows:
alert('foo');
No Self Assignment
Self assignments are useless. Therefore, it shouldn’t be in our code.
It’s probably an error that we haven’t caught when we changed our code.
For instance, the following are useless:
a = a;
[a, b] = [a, b];
Instead, we should write something like:
a = b;
[a, b] = [b, a];
No Self Compare
Comparing a variable to itself always returns true
. Therefore, it’s pretty useless to have these kinds of expressions in our code.
It’s usually an error from typing or refactoring our code. This may introduce runtime errors in our code.
The only time that it may be appropriate to compare a value against itself is when comparing NaN
since NaN
doesn’t equal itself when compared with the ===
operator.
But it’s better to check for NaN
using the isNaN
or Number.isNaN
functions to check for NaN
.
isNaN
tries to convert its argument to a number before checking for NaN
, while Number.isNaN
just check for the value without doing anything data type conversion first.
Therefore, we shouldn’t have code like the following:
const a = 1;
`if (a === a) {
x = 2;
}`
Don’t Use the Comma Operator
The comma operator always returns the last element from the list of items separated by the operator, evaluating them from left to right.
Therefore, it’s not a very useful operator to be using in our code.
We should probably remove any use of it from our code. So something like:
const a = (1, 2, 3);
will always set a
to 3.
There aren’t any valid use cases for this operator in a normal program.
Photo by Daiji Umemoto on Unsplash
Only Throw Error Object in throw Expressions
In JavaScript, we can put any value after throw
when we try to throw errors.
However, it isn’t good practice to throw anything other than the Error
object or a child constructor derived from it.
The Error
object automatically keep track of where the Error
object was built and originated.
For instance, we should have throw
expressions like:
throw "fail";
Instead, we should write:
throw new Error("fail");
Conclusion
return await
is mostly useless except for try...catch
blocks. Comparing a variable or value to itself is mostly useless, as with assign a variable to itself.
Likewise, the comma operator is also useless as it always returns the last value in the list.
Errors that throw exceptions should always throw an Error
object or an instance of its child constructor.
Script URLs in JavaScript is also a bad practice because we’re running code within a string, which prevents any optimizations from being done and it may let attackers run arbitrary with our code.