Categories
JavaScript Best Practices

JavaScript Best Practices — Classes and Constructors

Spread the love

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at the best practices for dealing with classes and constructors.

Always Use the Class Syntax. Avoid Manipulating Prototype Directly

The class syntax in JavaScript is just syntactic sugar on top of the constructor function syntax.

To create a constructor function with an instance method, we have to write something like the following code:

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

Person.prototype.greet = function() {
  return `hi ${this.name}`;
};

In the code above, we have the Person constructor function, which has the name parameter. We set the name parameter to this.name .

Then we defined the greet instance method, we have the returns the string that has the word ‘hi’ with this.name .

this.name would be the name member that’s in the Person instance.

If we log the value of the following expression:

new Person('jane').greet()

Then that returns the string 'hi jane’ .

The old constructor function makes creating constructors harder. We’ve to add instances to its prototype property, which means that we can’t put all the members in one place.

Instead, we should use the class syntax, which lets us keep all the members inside one class.

For instance, with the class syntax, we can rewrite the code as follows:

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

  greet() {
    return `hi ${this.name}`;
  };
}

In the code above, we have the Person class, which encapsulates all the members of the constructor, including instance variables and methods, all in one entity.

That’s much better than adding properties to a prototype. Also, we make sure that we have our initialization code in the constructor method instead of within the function itself.

This is much clearer as we know for sure that the value of this is the Person instance. It’s not so clear what the value of this is in the constructor function example by reading the code.

Use extends for Inheritance

The extends keyword that we can add to a class makes doing inheritance with constructor function easily.

With it, we can create a child class that inherits from the parent class without creating constructor functions that have to call and modify prototype .

We’ll also get an error if we forgot to call the parent constructor by calling super in the constructor if we have the extends keyword.

For instance, instead of writing the following code with constructor functions as follows:

function Animal(name) {
  this.name = name;
}

Animal.prototype.greet = function() {
  return `hi ${this.name}`;
}

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Animal;

In the code above, we have to do many things to create a Dog constructor as the child of the Animal constructor.

We’ve to call the Animal constructor by writing Animal.call(this, name); . Then we have to create Dog ‘s prototype by calling Object.create with Animal ‘s prototype as we did with:

Dog.prototype = Object.create(Animal.prototype);

Also, we have to set the parent constructor for Dog to Animal by writing:

Dog.prototype.constructor = Animal;

As we can see, we need many lines to create a Dog constructor that inherits from Animal .

We can only make sure that we did that all that correctly by calling the greet method from the Dog instance as follows:

new Dog('jane').greet()

Since we did inheritance with constructors correctly, we can call the Animal constructor with ease.

We instead write the following with the class syntax:

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

  greet() {
    return `hi ${this.name}`;
  };
}

class Dog extends Animal {
  constructor(name, breed) {
   super(name);
    this.breed = breed;
  }
}

All we have to do in the code above is calling the parent constructor from Dog ‘s constructor with super and add the extends keyword. If we forgot to call super , we’ll get an error.

Also, the class member code is all within the curly brace so we can tell what

Therefore, using the class syntax with extends is much clearer. There’s also less chance for mistakes.

Conclusion

The class syntax should always be used instead of the constructor syntax. It’s better for defining standalone constructors and also for inheriting from other constructors.

The class syntax is equivalent to constructor functions.

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 *