Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Avoiding Bad Code

Spread the love

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at some bad code that should be avoided if we want to write more robust JavaScript code.

Avoid Large Modules

Large modules are bad because they have too many members, which makes them hard to track and debug.

Longer pieces of code are also hard to read.

Modules should be small. For instance, we can have one module that only does mathematical operations.

We can write something like the following:

export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

The code above is short and easy to read.

Avoid Modules With Multiple Responsibilities

Modules with multiple responsibilities are probably doing too much.

This violates the single responsibility principles which are bad because it’s confusing to have many different things going on in one piece of code.

Modules with multiple responsibilities are confusing for many people since they do too many things. It’s not logical to have one module to be doing more than one thing.

For instance, if we have:

export const add = (a, b) => a + b;
export const foo = () => console.log("foo");

then that’s bad because we have functions in a module that do multiple kinds of things.

We have an add function that adds 2 numbers, and another function that logs 'foo' .

This doesn’t make sense since it does multiple things. This makes using it harder since we’ve to look at it to find out what the module does.

If the module only does one thing and the module name suggests that it’s so, then people don’t have to look too hard to find out what a module is doing.

Avoid Tight Coupling

Tight coupling is bad because it’s easy to break code when we need to change it, which is inevitable.

To avoid tight coupling, we should avoid exposing too many members from a module to the outside.

When 2 modules are tightly coupled, this means that 2 classes have to change together.

On the other hand, loose coupling of modules means that they’re mostly independent.

Other entities that may be tightly coupled include classes and functions. For instance, if we have the following code:

index.js

import { greet } from "./module";
export class Person {
  constructor(name) {
    this.name = name;
  }

  greet(greeting) {
    greet(`${greeting} ${this.name}`);
  }
}

module.js

import { Person } from "./index";
export const greet = greeting =>
  console.log(`${greeting} ${new Person("foo")}`);

In the code above, we have the greet function outside index.js and we imported Person in the greet function. In index.js , we have the Person class that imported the greet function from module.js .

This kind of dependency structure is too tightly coupled because Person depends on greet and greet depends on Person .

When one changes, we’ve to worry if it breaks the other, which isn’t good since it makes our code more fragile and slows us down when we try to make changes.

It’s better for them to be independent. If we don’t need them to be dependent on the other, then we should eliminate that dependency.

For instance, we can write the following:

index.js

class Person {
  constructor(name) {
    this.name = name;
  }

  greet(greeting) {
    console.log(`${greeting} ${this.name}`);
  }
}

module.js

export const greet = greeting => console.log(greeting);

In the code above, we kept them independent by eliminating the imports and referencing of the dependencies.

This is much cleaner and we don’t have to worry about breaking things outside of the code the module the items are in since they don’t depend on each other.

Avoid Magic Numbers

Magic numbers are numbers that occur in multiple places with an unexplained meaning. They’re often used as constants.

Since they’re used as constants, they should be replaced with named constants.

For instance instead of writing the following:

const foo = 1;
const bar = 1;
const baz = 1;

We should use a named constant instead of 1. For instance, we can write the following:

const CONSTANT = 1;
const foo = CONSTANT;
const bar = CONSTANT;
const baz = CONSTANT;

This way, we know that 1 is constant and give it meaning. Constant names in JavaScript are usually upper-case to make it clear that it’s a constant.

Conclusion

To write robust JavaScript, we should create small modules that only does one thing.

Tight coupling between entities should be eliminated. Finally, magic numbers should be avoided and should be replaced with constants.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *