Categories
Refactoring

JavaScript Refactoring — Functions and Classes

Spread the love

We can clean up our JavaScript code so that we can work with them more easily.

In this article, we’ll look at some refactoring ideas that are relevant for cleaning up JavaScript conditionals.

Introduce Parameter Object

If our function has multiple parameters, we can combine them into one object parameter and use that instead.

For instance, if we have the following code:

const getAmountFromRange = (start, end) => {
  //...
}

We can instead write the following code:

const getAmountFromRange = ({
  start,
  end
}) => {
  //...
}

The fewer parameters we need, the better our function is.

Remove Setting Method

If we have extra setters that we never use, then we can remove them from our class.

For instance, instead of writing the following class:

class Employee {
  setUselessValue() {
    //,..
  }
}

We can remove the useless setter as follows:

class Employee {
  //...
}

Replace Constructor with Factory Method

If we want to do more things than a simple constructor can do, then we can replace it with a factory method.

For instance, instead of just having the following class:

class Employee {
  constructor(type) {
    this.type = type;
  }
  //...
}

We can have a factory function that takes instantiates the class according to the type that’s passed in:

class Employee {
  constructor(type) {
    this.type = type;
  }
  //...
}

const createEmployee = type => new Employee(type);

This lets us create employees of all types with one function.

Replace Error Code with Exception

We can replace error codes with exceptions so that errors are more obvious to us when we occur.

For instance, if we have the following function:

const deposit = (amount) => {
  if (amount < 0) {
    return -1;
  }
  //...
}

We can instead throw an exception as follows:

const deposit = (amount) => {
  if (amount < 0) {
    throw new Error('amount must be bigger than or equal to 0');
  }
  //...
}

Exceptions are more obvious that return codes, so we should use throw exceptions instead.

Error codes like -1 are meaningless without explanation or assigning them to constants.

Replace Exception with Test

We can also replace exceptions with conditionals to check the value so that we don’t have to use try...catch blocks everywhere.

For instance, instead of writing:

const getItemByIndex = (arr, index) => {
  try {
    return arr[index].foo;
  } catch (ex) {
    console.error(ex);
  }
}

We can write the following:

const getItemByIndex = (arr, index) => {
  if (typeof arr[index] === 'undefined') {
    return;
  }
  return arr[index].foo;
}

This way, we don’t have to make our code more complex by introducing try...catch , which makes the workflow less linear.

Pull Up Field

If 2 or more subclasses have the same field, then we can pull them up to the superclass.

For instance, instead of writing the following code:

class Employee {}

class Cook extends Employee {
  constructor(name) {
    this.name = name;
  }
}

class Manager extends Employee {
  constructor(name) {
    this.name = name;
  }
}

We write:

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

class Cook extends Employee {

}

class Manager extends Employee {

}

This is better since name is in the Employee class rather than duplicated in multiple subclasses.

Pull Up Method

Likewise, if we have 2 or methods that are duplicated in multiple subclasses, we can pull them up to the superclass.

For instance, instead of writing the following code:

class Employee {}

class Cook {
  speak() {
    //...
  }
}

class Manager {
  speak() {
    //...
  }
}

We can instead write the following:

class Employee {
  speak() {
    //...
  }
}

class Cook extends Employee {
  //...
}

class Manager extends Employee {
  //...
}

Again, we eliminated duplication, which is good.

Conclusion

We can eliminate duplication by moving duplicate fields and methods to the superclass.

Also, we can group multiple parameters into objects so that we can reduce the number of parameters in a function.

We also don’t have to always throw exceptions, we can check for what we’re looking for before proceeding in our code instead.

However, sometimes we may want to throw exceptions instead when we’re returning error codes.

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 *