Oct
14
2019

Classes In Javascript

In Object Oriented Programming, a class provides a blueprint for creation of an object in Javascript. That means that when you specify a class including its variables and methods, you can create infinite new objects from it. It is useful because it reduces the amount of code we need to write when we want multiple objects that are similar to one another.

Defining a Class

Defining a class in JavaScript is simple thanks to the built-in class keyword. Let’s say we have a user and want a JavaScript object to represent each user. Thus, we create a userclass.
Syntax Of a “Class”:


Class user{

}
Let user = new user();
Console.log (user);

We have created a new User object using our defined class, assigned it to the user variable.

Constructing a Class

The constructor() method is called automatically by new, so we can initialize the object there. Then we can call object methods, such as user.sayHi().

For Example:


class User {

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

  sayHi() {
    alert(this.name);
  }

}
// Usage:
let user = new User("XYZ");
user.sayHi();

In this case, we are using the constructor keyword. You can think of constructor as just a special function that asks for the data required to create a new object out of the class. Since we want every user to have a name we are specifying that in our constructor.

Class Inheritance

While our current solution works for now, it can certainly be improved upon. Our Petclass doesn’t offer any distinction between a cat or a dog, which each would have additional information that doesn’t apply to the other. Luckily for us, JavaScript offers class inheritance, which means we can create new classes that inherit everything from another, but adds unique information for itself.

This means that since a dog is still a pet, we can just inherit from the Pet class and add any dog-specific stuff in the Dog class. To keep things basic, let’s add the ability to bark if it’s a dog.

For Example:


class Dog extends Pet {
        bark() {
            console.log("BARK BARK BARK");
        }
    }

    let dog = new Dog("Cooper", 20, 200);
    console.log(dog.getInfo());

    dog.bark();

We created a new Dog, but since it is still a pet because we inherited from the Pet class, it was able to both bark, something only dogs can do, but also return back info thanks to the getInfo function, something any pet can do.

The information we passed to the Dog class is automatically passed to the Pet class which is how getInfo worked as expected.

Function Overriding And Super Keyword

To serve as an introduction to another useful JavaScript feature, let’s create a Cat class. This time, we’ll have all cats have a unique feature that they each have a favorite brand of cat food, and thus will need a string to keep track of that.


class Cat extends Pet {
        constructor(name, weight, price, brand) {
            super(name, weight, price);
            this.brand = brand;
        }
        getFavoriteBrand() {
            return this.brand;
        }
        getInfo() {
            return "Hi, I'm a cat named " + this.name + " and I like " + this.brand +  ". I weigh " + this.weight + " pounds and cost $" + this.price + ".";
        }
    }

    let honey = new Cat("Honey", 15, 300, "Purina");
    console.log(honey.getInfo());
    console.log(honey.getFavoriteBrand());

A couple of very interesting things is happening here. First, in the constructor for Cat, you’ll notice the super keyword. This is simply manually calling the constructor of the class that Cat is inheriting from, in this case, the Pet class. The only reason this is needed is because we added a new parameter to the constructor of Cat, and that is the brand string.

Since brand is unique to cats, we assign it under the super call.

The second interesting thing that is happening here is that we defined a getInfo function inside Cat, even though there is already one inside Pet. When we do this, we are overriding the function, which means that cats will use the one defined in Cat instead of Pet, which is what we want.

Classes in JavaScript are extremely useful and versatile, as these examples have hopefully shown. You can define base classes (the Pet class) and create an endless number of classes that inherit from it (the Dog and Cat classes) which have their own unique features and functionality only private to them, which still retaining the features and functionality available to all.

You could even go further and have different breeds of dogs and cats have their own classes that inherit from the Dog and Cat class

Private Class Fields

Relatively new to JavaScript are private class fields. A class field is a variable that is maintained inside a class. Previously, there was no way to denote that a field should only be accessible to the class itself and not for outsiders. We got around this limitation by adding an underscore in the variable name. Here’s an example:


    class Number {
        _value = 0;

        increment() {
            this._value++;
        }
    }

To other developers, the underscore would imply that the variable is only meant to be accessed internally, but nothing prevented you from doing this in another file:


    const number = new Number();
    console.log(number._value);

However, with the introduction of truly private class fields, we can let JavaScript enforce this for us:


    class Number {
        #value = 0;

        increment() {
            this.#value++;
        }
    }