JavaScript Refactoring — More Conditionals
Tags: codequality, webdev, programming, javascript
Published: 2021-01-25 03:22:20

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

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.