5 Tips for Writing Cleaner Code
1. Avoid Unnecessary Nesting
Too much nesting can make code harder to read and more prone to errors, so we can use an early return to avoid excessive nesting.
// Bad
function deleteItem(item) {
if (item != null) {
console.log('Deleting item');
item.delete();
}
}
// Good
function deleteItem(item) {
if (item == null) return;
console.log('Deleting item');
item.delete();
}
Nested if example:
// Bad
function saveItem(item) {
if (item != null) {
console.log("Validating");
if (item.isValid()) {
console.log("Saving item");
item.save();
}
}
// Good
function saveItem(item) {
if (item == null) return;
console.log("Validating");
if (!item.isValid) return;
console.log("Saving item");
item.save();
}
2.Make Use of Destructuring
We often accept an Object as a parameter within a function. At this time, we can use destructuring to destructure this Object, so that we can directly use the properties of the Object to obtain data.
Example without using destructuring:
// not so good
function getFullName(person) {
const firstName = person.firstName;
const lastName = person.lastName;
return `${firstName} ${lastName}`;
}
Example with destructuring:
// good
function getFullName(person) {
const { firstName, lastName } = person;
return `${firstname} ${lastName}`;
}
// better
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
3. Use Pure Functions to Avoid Side Effects
When writing a function, it is best not to use variables outside the function, so as to avoid side effects.
// bad
let items = 5;
function changeNumber(number) {
items = number + 3;
return items;
}
changeNumber(5);
In the example above, we use items, a global variable, within changeNumber. This approach is prone to unpredictable situations, such as when items no longer exists or its data type is changed, which can lead to errors.
To avoid the above-mentioned side effects, we can rewrite it using the Pure Function approach:
// good
function addNumByThree(number) {
return number + 3;
}
In the example above, we removed the dependency on external variables, making its functionality completely independent and not affecting other parts. Therefore, we can more easily predict the behavior of the function.
4. 4. Make Functions Do One Thing Well
When writing functions, it is best not to do too much, which can reduce the complexity and side effects of the function.
Bad example:
// Bad
function validateAndSignUp() {
// Do a heap of stuff here
}
The above approach can easily make our code too complicated, eventually becoming a Spaghetti code, and also make the code difficult to reuse, maintain, and debug. Therefore, we can break it down into small units:
function validate() {
// Validate Input
}
function signUp() {
// Sign Up User
}
5. Use Meaningful Names
- When Function is an action, name it using a verb.
// bad
function passwordValidation() {
// ...
}
// good
function validatePassword() {
// ...
}
- If the variable is a
Boolean, prefix it withis.
const isValidPassword = validatePassword('abcd');
- If the variable is an
Array, name it in plural or with alistsuffix.
// bad
const animal = ['cat', 'dog', 'bird'];
// good
const animals = ['cat', 'dog', 'bird'];
const animalList = ['cat', 'dog', 'bird'];
- When using a
callback, always use meaningful names when iterating:
// Really bad
animals.forEach(a => {
console.log(a);
});
// Good
animals.forEach(animal => {
console.log(animal);
});