JavaScript Refactoring — Classes and Objects

John Au-Yeung - Jan 25 '21 - - Dev Community

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 classes and objects.

Replace Data Value with Object

If we want to store things that can’t be stored in any primitive type, then we need to store them in an object.

For instance, instead of writing:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}

const purchase = new Purchase('joe');
Enter fullscreen mode Exit fullscreen mode

We write:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}

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

const customer = new Customer('joe');
const purchase = new Purchase(customer);
Enter fullscreen mode Exit fullscreen mode

This way, in addition to the name, we can add other properties to the Customer instance as we desire.

Whereas in the first example, customer isn’t encapsulated in its own object.

Change Value to Reference

We can turn an object with many equal instances into a many to one relationship.

For instance, if we have many customers with the same order, then instead of having many purchase objects that only reference one customer object, we can reference many purchases in one customer object.

For instance, instead of writing the following:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}

class Customer {
  //...
}

const customer = new Customer('joe');
const purchase = new Purchase(customer);
Enter fullscreen mode Exit fullscreen mode

And repeat the same with all the other purchases, we write:

class Purchase {
  constructor(customesr) {
    this.customers = customers;
  }
}

class Customer {
  //...
}

const joe = new Customer('joe');
const jane = new Customer('jane');
const purchase = new Purchase([joe, jane]);
Enter fullscreen mode Exit fullscreen mode

This way, we don’t need a new customer entry for each new purchase object.

Change Reference to Value

We can also turn a many to one relationship between classes to one. For instance, if we only have one object that always references one other class, then we can turn it into a one to one relationship between them.

For instance, instead of writing:

class Purchase {
  constructor(currencies) {
    this.currencies = currencies;
  }
}

class Currency {
  //...
}

const usd = new Currency('usd');
const purchase = new Purchase([usd]);
Enter fullscreen mode Exit fullscreen mode

We write:

class Purchase {
  constructor(currency) {
    this.currency = currency;
  }
}

class Currency {
  //...
}

const usd = new Currency('usd');
const purchase = new Purchase(usd);
Enter fullscreen mode Exit fullscreen mode

Replace Array with Object

We should change an array to an object if each entry has different types of data that should be grouped together.

For instance, instead of writing:

const joe = ['joe', 12];
Enter fullscreen mode Exit fullscreen mode

We write:

const joe = {
  name: 'joe',
  age: 12
}
Enter fullscreen mode Exit fullscreen mode

Instead of putting the name and age into an array, we move them into an object with their own property names to make everyone clear what they are.

Change Unidirectional Association to Bidirectional

We can change a unidirectional relationship between 2 classes to a bidirectional one.

For instance, instead of writing:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}
class Customer {
  //...
}
Enter fullscreen mode Exit fullscreen mode

We write:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}

class Customer {
  constructor(order) {
    this.order = order;
  }
}
Enter fullscreen mode Exit fullscreen mode

There’re situations where both classes want to access each other’s data, so we reference each other in each class.

Change Bidirectional Association to Unidirectional

We can also reverse the action we did above and change the bidirectional association to unidirectional.

So we can turn the following:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}

class Customer {
  constructor(order) {
    this.order = order;
  }
}
Enter fullscreen mode Exit fullscreen mode

back to:

class Purchase {
  constructor(customer) {
    this.customer = customer;
  }
}

class Customer {
  //...
}
Enter fullscreen mode Exit fullscreen mode

It the Customer class doesn’t need anything from Purchase , then we can take it out.

Conclusion

We can change the relationships of classes from unidirectional and bidirectional and vice versa depending on if we need to access the data from each class or not.

If we need to store more data than a primitive than store in a class field, then we can turn it into an object.

We can also change class relationships to one to many and vice versa depending on how many of a thing we need in a field.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .