JavaScript Clean Code — More About Classes

John Au-Yeung - Jul 24 '20 - - Dev Community

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

Follow me on Twitter at https://twitter.com/AuMayeung

Many more articles at https://medium.com/@hohanga

Even more articles at http://thewebdev.info/

Classes in JavaScript is syntactic sugar on top of the prototypical inheritance features of the language. However, in terms of writing clean code, the principles still apply since they have the same structure as classes in class-based languages.

In this article, we’ll look at how to write JavaScript classes in a clean and maintainable way.

We’ll look at how to organize for changes and using the class syntax instead of using constructor functions.

Organizing for Change

We have to prepare for classes to be changed when we organize them. This means that we should make them extendible rather than having to constantly modify code to get the functionality we want in our class.

Our methods should be simple. Simple methods are easier to test and we don’t have to change them as much.

We should follow the open/closed principle, which states that a piece of code should be open for extension but closed for modification.

This applies to classes just like another piece of code.

For example, if we have the following Rectangle class:

class Rectangle {
  constructor(length, width) {
    this.length = length;
    this.width = width;
  }

  get area() {
    return this.length * this.width;
  }
}

Then we can easily add a getter method for computing the perimeter of a rectangle as follows:

class Rectangle {
  constructor(length, width) {
    this.length = length;
    this.width = width;
  }

  get area() {
    return this.length * this.width;
  }

  get perimeter() {
    return 2 * (this.length + this.width);
  }
}

As we can see, we didn’t have to modify the existing code to add a method for computing the perimeter. We just add the perimeter getter method and be done with it.

Use the Class Syntax Instead of Constructor Functions

It’s time to move on to the class syntax instead of using constructor functions.

We can see why with the following example of inheritance:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

function Employee(name, age, employeeCode) {
  Person.call(this, name, age);
  Employee.prototype.constructor = Person;
  this.employeeCode = employeeCode;
}

First, we have to create the Person constructor, then to make Employee ‘s prototype Person and set all the inherited properties, we have to first write:

Person.call(this, name, age);

to set all the instance variables, and:

Employee.prototype.constructor = Person;

to set the Employee’s prototype constructor to Person . We can easily miss any of these 2 lines and the Employee constructor won’t be inheriting from the Person constructor.

If we create an Employee instance as follows:

const employee = new Employee('Joe', 20, 'waiter');

Then we should see something like the following under the __proto__ property:

constructor: _ƒ Person(name, age)_

This means that we set the prototype of the Employee instance to the Person constructor correctly.

With the class syntax, we only have to use the extends keyword to inherit from one class. We can rewrite the code above as follows:

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

class Employee extends Person{
  constructor(name, age, employeeCode) {
    super(name, age);
    this.employeeCode = employeeCode;
  }
}

Then when we create the same Employee instance as follows:

const employee = new Employee('Joe', 20, 'waiter');

Then we should see something like the following under the __proto__ property:

constructor: _class Employee_

As we can see, both console.log outputs are the same, except for the function and class difference, but they’re the same since classes are the same as constructor functions.

However, we don’t have to use call or this , and set the variables of the superclass manually.

The JavaScript interpreter will tell us if we forgot to call super or use the extends keyword.

There’s no going back to the old constructor function syntax nowadays since it’s pretty inconvenient.

Conclusion

When we design classes, we should organize for change. This means that we should have code that’s open for extension but closed for modification.

This reduces the risk of messing up existing code why allowing us to keep making changes by adding new code.

Also, it’s time to move on to the class syntax for creating constructor functions. It’s hard to do inheritance with old constructor functions, while the class syntax makes everything much easier.

The post JavaScript Clean Code — More About Classes appeared first on The Web Dev.

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