Creating maintainable JavaScript code is important if want to keep using the code.
In this article, we’ll look at the basics of creating maintainable JavaScript code by looking at separating app logic from event handling.
Also, we look at how to check for primitive values.
Event Object
When we’re handling events, we should keep the event
object in the event handler only.
This will reduce coupling in our code.
So if we need to use something from the event
object, we keep them in the event handler.
For instance, we can write:
function onclick(event) {
const {
clientX,
clienty,
preventDefault,
stopPropagation
} = event;
preventDefault();
stopPropagation();
showPopup(clientX, clienty);
}
function showPopup(x, y) {
const popup = document.getElementById("popup");
popup.style.left = `${x}px`;
popup.style.top = `${y}px`;
popup.className = "popup";
}
const button = document.querySelector('button');
button.addEventListener('click', onClick);
We called the preventDefault
and stopPropagation
methods in from the event
object in the event handler.
This is much better than passing the event
object and call it in that function.
We don’t want our app logic code and event handling code to mix.
This way, we can change the app logic and event handling code independently.
And we can call the app logic code directly.
So we can write something like:
showPopup(10, 10);
It also makes testing a lot easier since we can call showPopup
directly to test it.
Avoid Null Comparisons
A common problematic pattern in JavaScript code is testing variables against null
.
For instance, we may have code like:
function process(items) {
if (items !== null) {
items.sort();
items.forEach((item) => {
//...
});
}
}
We have the process
function that checks the items
against null
.
Then we assume items
is an array and call sort
and forEach
on it.
Comparing against null
doesn’t mean we made sure that it’s an array.
We only know that it’s not null
.
We can improve our value comparison so that we can actually check for what we want.
Detecting Primitive Values
There’re a few types of primitive values in JavaScript.
They include bigints, strings, numbers, booleans, null
and undefined
.
The typeof
operator is the best one for checking for types of primitive values.
We just need to pass in the expression we want to check as the operand.
For strings, typeof
returns 'string'
.
For numbers, typeof
returns 'number'
.
For boolean, typeof
returns 'boolean'
.
For bigints, typeof
returns 'bigint'
.
And for undefined
, typeof
returns 'undefined'
.
The basic syntax for typeof
is:
typeof variable
We can also write:
typeof(variable)
However, the 2nd way makes tyepof
looks like a function.
Therefore, we should use it without parentheses.
We can code defensively bu using the tupeof
operator to check the type of the value of the expression.
For instance, we can write:
if (typeof name === "string") {
let part = name.substring(3);
}
to check a string.
We can write:
if (typeof count === "number") {
setCount(count);
}
to check for and set a number.
And:
if (typeof canShowMessage === "boolean" && canShowMessage) {
showMessage("hello");
}
to check for a boolean and whether it’s true
or not.
And we can write:
if (typeof app === "undefined") {
app = {
// ....
};
}
to check for undefined
.
Conclusion
We shouldn’t make our app logic depend on the event
object.
Also, checking for null
isn’t good enough for checking most types of data.