Classes In Javascript

Classes In Javascript

Introduction

What is a class?

According to Wikipedia, a class in object-oriented programming is an extensible program-code template for creating objects, providing initial values for state (member variables) and implementations of behaviour (member functions or methods.

In practice, often we need to create many objects of the same kind such as products, users and so on. Classes provide a more advanced way to do just that. Such an object created from a class is called an “instance of a class”.

Prototypes are used for defining properties that all instances of a class have in common. Properties that differ per instance need to be stored directly in the objects themselves.

The basic syntax of a class is:

class someClass {
    // methods
}

Let's create an Animal class:

class Animal {
    constructor(name, age, gender, sound) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.sound = sound;
    }

    greeting() {
        console.log(`${this.sound}, my name is ${this.name}.`)
    }
}

The class keyword starts a class declaration, which allows us to define a constructor and a set of methods in a single place. Any number of methods may be written inside the declaration. The special constructor methods will be bound to the name Animal. The others are packaged into that constructor’s prototype.

Like functions, class can be used in both statements and expressions. For example;

let object = new class {
    greeting() {
        return "Hello";
    }
}

console.log(object.greeting());
// Hello

So to create an instance of a given class, you have to create an object that derives from the proper prototype. It is important to make sure that the object itself has the properties that instances of the given class are supposed to have. This is where the constructor function comes in.

A constructor function is a special function in javascript that is used to define and initialise functions and their features.

To create a new object with all the listed methods from Animal, the "new" method is used. The constructor method is automatically called by new, so we can initialise the new object.

let theDog = new Animal('Stunner', 4, 'male', 'Woof!');
theDog.greeting(); 

// Woof! My name is Stunner.

Inheritance With Classes

The Animal class we created above has a series of attributes that are common to all animals. Now, we will create a specialised Cat class, making it inherit from Animal. This is called creating a subclass.

To create a subclass, we use the “extends” keyword to tell javascript the class we want to base our class on.

class Cat extends Animal {
    constructor(breed, country) {
        this.breed = breed;
        this.country = country;
    }
}

Unlike in the old method of using constructor functions, where the new operator initialises the “this” keyword to a newly allocated object, it isn’t the case for a class defined by the "extends" keyword.

For sub-classes, the "this" initialisation to a newly allocated object is always dependent on the parent class constructor.

Here we are extending the Animal class I.e the Cat is an extension of the Animal class. So for Cat, the this initialisation is done by the Animal constructor.

To call the Animal constructor, we have to use the super() operator.

class Cat extends Animal {
    constructor(breed, country) {
        super();
        this.breed = breed;
        this.country = country;
    }
}

Since the super() operator is actually the parent class constructor, passing it the necessary arguments of the Animal class constructor will also initialise the parent class properties in our sub-class, thereby inheriting it.

class Cat extends Animal {
    constructor(name, age, gender, sound, breed, country) {
        super(name, age, gender, sound);
        this.breed = breed;
        this.country = country;
    }
}

Now when we instantiate Cat object instances, we can call properties and methods defined on both Cat and Animal as we would expect.

let Garfield = new Cat('Garfield', 2, 'male', 'Purr', 'Persian', 'Iran');
Garfield.greeting(); // Purr, my name is Garfield.

Garfield.age; // 2
Garfield.country; // Iran

Getters And Setters

Getters and Setters are functions used to control access to an object.

Getter functions are used to return the value of an object's private variable to a user without directly granting access to the user.

Setter functions are used to modify the value of an object's private variable based on the parameter passed into the function.

class Movie {
    constructor(director) {
        this.director = director;
    }

    get theDirector() {
        return this.director;
    }

    set theDirector(newDirector) {
        this.director = newDirector;
    }
}

const JusticeLeague = new Movie('Joss Whedon');
console.log(JusticeLeague.theDirector); // Joss Whedon

JusticeLeague.theDirector = 'Zack Snyder';
console.log(JusticeLeague.theDirector); // Zack Snyder

Resources

MDN

Eloquent JavaScript

Conclusion

Classes in JavaScript were a very helpful addition to the language because they provide a cleaner and generally better way of creating objects.