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 how to declare variables the right way and writing better Node apps by cleaning up require
calls and handling errors.
Don’t Use Restricted Names as Identifiers
We shouldn’t use restricted names like undefined
, NaN
, or Infinity
as identifiers for variable names, functions, etc.
It confuses the user by thinking that we’re actually doing the assignment to those values when that’s not actually being done.
For instance, if we have:
var NaN = "bar";
Then that’s deceptive since most people would assume that 'bar'
is set as the value of undefined
.
However, when we log the value of undefined
, we still get undefined
.
JavaScript’s strict mode would prevent something like the code above from running.
Also, we’ll also get errors if we declare the undefined
variable with let
or const
.
Do Not Use undefined
As a Variable
Theoretically, since the JavaScript undefined
value is a global variable, we may be able to overwrite it with some other value.
However, we can write something like the following:
var undefined = "bar";
and not get errors if strict mode if off. No assignment was actually done, but the code runs.
Therefore, we shouldn’t use undefined
as a variable name in any situation since it doesn’t do the assignment as we expected it to. If it does, then it would be scarier since we expect undefined
to be undefined
.
No Unused Variables
Unused variables are dead and useless code. Since they aren’t being used anywhere, they should be removed from our codebase.
Declarations like:
let x;
that isn’t referenced anywhere else should be removed.
If we declare a variable, we should either use it or remove it.
Don’t Use Variables Before it’s Defined
If we declare a variable with var
, then we can use it before it’s declared because the variable declaration itself is hoisted.
For instance, we can use it as follows if we have a variable declared with var
:
console.log(foo);
var foo = 1;
In the code above, we would see that foo
is undefined
from the console log output since the variable was hoisted, but the value assignment is still done in its original position.
This is very confusing for lots of people, so we shouldn’t use variables before they’re declared.
Better yet, we should use let
and const
to declare variables and constants respectively so that we don’t have about issues like this.
let
and const
variables and constants are block-scoped so that their scope stays inside the block.
Also, they aren’t hoisted so they can’t be referenced before they’re declared. Therefore, we’ll get an error if we try to reference it before it’s declared.
Put require() On the Top of a Module File
require
should be added to the top of a module file. It’s cleaner and we get all the imported modules members all in one place.
This way, we don’t have to worry about using module members that haven’t been imported yet since if we see them all at the top, then we know that they’re imported right away.
Therefore, the following code:
const fs = require("fs");
const readFile = (fileName) => {
const file = fs.readFileSync(fileName);
return file;
}
readFile('foo.txt');
is better than:
const readFile = (fileName) => {
const fs = require("fs");
const file = fs.readFileSync(fileName);
return file;
}
readFile('foo.txt');
Even though both are valid imports. It’s just that the first example is cleaner as we put all the require
calls in one place.
Do Callback Error Handling
If a callback function has the err
parameter. Then we should probably do something to check if anything is set as the value for the err
parameter before proceeding.
We can handle this by writing the following:
const fs = require("fs");
const readFile = (fileName) => {
fs.readFile(fileName, (err, data) => {
if (err) {
throw err;
}
console.log(data);
});
}
readFile('foo.txt');
The callback we have above, we wrote:
if (err) {
throw err;
}
to throw the err
object if an error is encountered. Then we can handle it somewhere else.
Conclusion
Restricted names like undefined
or NaN
shouldn’t be used as identifiers for anything like variables or functions.
In Node apps, require
should be on the top of the file to make the require
calls easier to read since they aren’t scattered everywhere.
Finally, if we have errors in our callbacks, we should handle them.