Categories
Refactoring

JavaScript Refactoring — More Conditionals

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 Assertion

We can add assertions to check for the parameters passed in by adding assertions.

This way, assumptions are made explicit.

For instance, we can write the following to add an assertion:

const assert = require('assert');
const foo = (val) => {
  assert.equal(val, 50);
  //...
}

The code above works for Node.js since it uses the Node.js’s assert module.

We check if val is 50 before proceeding. If the assertion is false, the function will end.

Rename Method

If our method name isn’t clear enough, then we should rename it so that it’s clearer.

For instance, instead of writing:

class Person {
  ga() {
    //...
  }
}

We write:

class Person {
  getAge() {
    //...
  }
}

getAge is much clearer than ga , so we should rename it.

Add Parameter

We can also add parameters to methods. For instance, instead of writing:

class Person {
  getContact() {
    //...
  }
}

We write:

class Person {
  getContact(date) {
    //...
  }
}

We added the date parameter to make getting what we want easier.

Separate Query From Modifier

If we have a method that returns and value and changes the state of the object, then we should break them up into separate methods.

This way, they only do one thing each.

For example, instead of writing:

class Purchase {
  setPurchaseDateAndGetTotalPrice() {
    //...
  }
}

We write:

class Purchase {
  setPurchaseDate() {
    //...
  }

  getTotalPrice() {
    //...
  }
}

Not only the names of the methods are shorter, but their bodies also do less and only one thing so it’s better.

Parameterize Method

Instead of having multiple methods doing similar things, we can have one method that takes a parameter that does something that all the methods do.

For instance, instead of writing:

class Purchase {
  fivePercentDiscount() {
    //...
  }

  tenPercentDiscount() {
    //...
  }
}

We write:

class Purchase {
  discount(percent) {
    //...
  }
}

Replace Parameter with Explicit Methods

If we have a method with parameters and different things are done according to those parameters, we can separate them out into their own methods.

For instance, instead of writing:

class Person {
  getDimension(type) {
    if (type === 'height') {
      return this.getHeight();
    } else if (type === 'weight') {
      return this.getWeight();
    }
  }

  getHeight() {
    ///...
  }

  getWeight() {
    ///...
  }
}

We write:

class Person {
  getHeight() {
    ///...
  }

  getWeight() {
    ///...
  }
}

As we can see, the getDimension isn’t all that useful to begin with, so we can remove it and call those getHeight and getWeight directly.

Preserve Whole Object

If we have to get multiple values from an object and pass them all into a function, then we should just pass in the whole object instead.

For instance, instead of writing:

const calculate = (height, weight) => {
  //...
}

const height = getDimensions().height;
const weight = getDimensions().weight;
calculate(height, weight);

We write:

const calculate = ({
  height,
  weight
}) => {
  //...
}

const dimensions = getDimensions();
calculate(dimensions);

We just pass in the whole object instead of passing in individual properties.

To make the calculate function more readable, we used destructuring to get the properties that we want to get from the object.

Replace Parameter with Method

We can replace a parameter with its own method. For instance, if we have:

const getDiscountLevel = () => {
  //...
  return 0.5;
};

const discountedPrice = (subtotal, discountLevel) => {
  return subtotal * discountLevel
}
const subtotal = 100
const discountLevel = getDiscountLevel();
const total = discountedPrice(subtotal, discountLevel);

We can just replace discountLevel with the getDiscountLevel function call itself as follows:

const getDiscountLevel = () => {
  //...
  return 0.5;
};

const discountedPrice = (subtotal) => {
  return subtotal * getDiscountLevel()
}
const subtotal = 100
const total = discountedPrice(subtotal);

Now we eliminated the parameter from discountedPrice and the discountLevel variable.

Conclusion

To add checks to a function before it’s run, we add some assertions with the Node assert module.

We can also rename methods to make them clearer. Also, methods that do multiple things should be broken down.

If we’re passing in multiple properties from the same object into a function, we should just make the function take the whole object.

Leave a Reply

Your email address will not be published.

If you like the content of this blog, subscribe to my email list to get exclusive articles not available to anyone else.