Menu Home

class

Hi everyone! And welcome to another exciting edition of Boring JavaScript. Today, we tackle classes in JavaScript …

THERE ARE NO CLASSES IN JAVASCRIPT!

Yes, I hear what you’re saying. So let’s address the elephant in the room first:

JavaScript classes are just syntactical sugar for a design pattern using functions. A class in the classical sense does not exist in JavaScript.

Are we happy? GOOD! Now, let’s dive in and take a look.

Skip the reading! See the video.

A Class Unto It’s Own

Classes are a computer science concept which describes a structure – like a blueprint – that shows how an object is to be created, what properties that object will have, and it’s behavior. Using a cat as an example, the cat will have a head, a body, some legs, a tail, and sharp teeth. These are the properties of the cat. The cat can bite, run, meow, and look down upon humans. These are the behaviors of the cat.

In terms of JavaScript classes, the properties are called … well … properties. The behaviors are called methods.

Let’s construct a simple class.

class Animal {
    constructor () {
        this.head = true;
        this.body = true;
        this.legs = 0;
        this.arms = 0;
        this.alive = false;
    }

    born () {
        this.alive = true;
    }
}

const myAnimal = new Animal();
const myOtherAnimal = new Animal();

In this class, called ‘Animal’, we have five properties and two methods. The first method, constructor, is a ‘reserved’ method. While not required, if you have a constructor method, it will always get executed when an instance of the class is created. And when is that instance created? When you use the new verb. Line 15 shows how new is used to create an instance. This is important. As mentioned above, a Class is nothing but a blueprint for creating copies of itself. Each copy is called an instance, and while each instance will have the same properties and methods, the value of a property changing in one instance will not change another instance.

Think of a house. There is a blueprint from which the house was built (class), and each house built from that blueprint is a copy of the blueprint, but each is separate from the other (instance). Classes in JavaScript – in fact in most computer languages – work exactly the same way.

Growing Up

Our Animal class doesn’t do much at all. Is my animal a cat? A dog? A dinosaur? We don’t know. But while dogs, cats, and dinosaurs are different animals, they do share something in common. They each have a head, a body, arms, legs, and are alive – just like our Animal above. Wouldn’t it be great if we could have classes to be both ‘cat’ and ‘animal’, or ‘dog’ and ‘animal’, or ‘dinosaur’ and ‘animal’.

Well you can! It’s called extending the class – and we do that using the extends verb.

Let’s look at an example:

import Animal from './Animal.js';

class Cat extends Animal {
    constructor() {
        super();
        this.tail = true;
    }

    speak() {
        // whatever JavaScript code plays an audio of a 'meow'
    }

    born() {
        super.born();
        this.legs = 4;
    }
}

const myCat = new Cat();

Line 1 assumes that our ‘Animal’ class is defined in another JavaScript file. The import statement brings that in.

Take a look at Line 3. It says “I’m going to create a new class called Cat and I want to use the class Animal as a basis for my class”. What happens is that JavaScript creates a blueprint for the Cat class based upon the blueprint of the Animal class. It will have all the same properties and methods of the Animal class. It will then add its own properties and methods specific to the Cat class. In this case, Cat adds a new property called “tail” and a new method called “speak”. These will only be available to any instance created from Cat. Any Animal will not have these new properties and methods.

Also notice we have a ‘constructor’ and ‘born’ methods in our Cat class. We also have those in the Animal class. So what happens?

Super Duper Man

Let’s look at our code again for the Cat class:

class Cat extends Animal {
    constructor() {
        super();
        this.tail = true;
    }

    speak() {
        // whatever JavaScript code plays an audio of a 'meow'. Not important to this example
    }

    born() {
        super.born();
        this.legs = 4;
    }
}

As mentioned, we have two methods the Animal class also uses – constructor and born. Which method takes precedence? They both do – and that’s all because of the reserved method super().

Whenever you extend another class, the super() method is called to execute a method that belongs to the extended class. Calling super() by itself is reserved for calling the constructor of the extended class, while calling a method of the super – super.method() – calls an individual method of the extended class.

In Line 3 we can see that in the Cat class. Within our constructor, the very first thing we do (and it should always be the first thing you do in a constructor) is to call super(). This loads up all the properties defined in the constructor of the extended class. In our case, that means that Cat will now have the properties ‘head’, ‘body’, ‘arms’, ‘legs’, and ‘alive’ that came from Animal, in addition to property we declared for Cat called ‘tail’.

In Line 12, we see how we can use super() within a method. Since Cat defines a born method (just like the Animal class), we need to execute the born method within the Animal class. To do that, we call the method off of the ‘super’ reserved object. In our case, that will set the value of the property ‘alive’ to boolean true. Then Cat sets the number of legs to 4 – because, well, cats have four legs. Do you have to call super.method()? No, but if you don’t, you won’t get the results you are expecting from the extended class. So be a good developer and call the super.method() on any method you redefine.

Static Electricity

The final thing I want to cover is the concept of static properties and static methods. Statics are properties and methods associated with the class definition, and not the instance of the class. This means that while normal methods and properties are created for each instance you create, static methods and properties are only accessed with the class definition itself and are NOT created with the instance.

Confused? Let’s take a look at an example:

class Animal {
    static TYPES = {
        cat: 0,
        dog: 1
    }

    static validType = function (type) {
        return Animal.TYPES[type] !== undefined;
    }

    constructor (type) {
        if (!Animal.validType(type)) {
            throw(new Error(`You cannot have a type of ${type}!`));
        }
        this.type = type;
    }
}

const myCat = new Animal('cat');
const myDog = new Animal('dog');
const myDinosaur = new Animal('dinosaur');  // throws error

Lines 2 and 7 define our static property (‘TYPES’), and our static method (‘validType’). Lines 8 and 12 show you how to use static properties and methods. Notice that we are not using ‘this’ here. That is because static properties and methods are associated with the class definition, not the instance. To access static properties and methods, you must get access to the class definition itself. Lines 8 and 12 show you how that is done.

How do we know this is true? If you did a console.log() on ‘myCat’ or ‘myDog’, then you will not see the property TYPES, and if you look at their prototypes you will not see the method ‘validType’. This proves that statics are not created with each instance.

What are statics good for? They are excellent for data structures like enumerated values which do not change but with are tied to the definition of a class.

The Whole Enchilada

The above will get you started using classes. But if go to the Mozilla Developer Network article on classes, you’d see there is a whole lot more there – like getter / setter properties, new ways to declare variables, and so much more.

Oh! And there’s even a proposal out there for Private Variables – coming Real Soon Now to a JavaScript runtime engine near you.

I suggest you pop over to the MDN docs mentioned above to read all the great things you can do with classes.

The Video

If all this reading was too much, just check out our video.

Shameless Plugs

We’re everywhere!

Facebook

YouTube

Twitter

Categories: Boring JavaScript Javascript

Tagged as:

thevirtuoid

Web Tinkerer. No, not like Tinkerbell.

Creator of the game Virtuoid. Boring JavaScript. Visit us at thevirtuoid.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: