DEV Community

Johnson Ogwuru
Johnson Ogwuru

Posted on

The syntactical Sugar Classes of JavaScript

In my previous article;

we looked at Getters and Setters as they apply to objects in JavaScript and i recall promising to show us how we could use getters in Es6 classes, We would also learn a great deal about classes.

First of; i wouldn't be talking about them differently. We would talk about classes and while writing some of our codes, i would show you how getter is used in the codes.

Classes
They are a tool most developers use to quickly produce similar objects.

let dog = {
            name: "lucky",
            breed: "American Bulldog.",
            age: 2

          }
Enter fullscreen mode Exit fullscreen mode

They code above looks like what we already know - objects. Now imagine you own a dog daycare and want to create a catalog of all the dogs who belong to the daycare, instead of using the syntax above for every dog that joins the daycare which would be undoubtedly burdensome, we can create a Dog class that serves as a template for creating new dog objects. Since you would be saving yourself they energy required to rewrite a code you already wrote for a particular dog, it would be safe to say that classes are a great way to reduce duplicate code and debugging time.

class syntax:

class Dog{
    constructor(){

    }
    method1(){

    }
    method2(){

    }

}
Enter fullscreen mode Exit fullscreen mode

Aha....i get the question in our heads, what is a constructor?...felt the same way though, lets talk about it a little.Also note the methods in the example above are normal functions we know, but when written inside a class they are called methods and are written without the function keyword.

Constructors
One notable difference that exists between objects and classes is the use of constructors in classes. JavaScript calls the constructor method every time it creates a new instance of a class.

class Dog{
    constructor(name,breed){
        this.name = name;
        this.breed = breed;
    }
    method1(){

    }
    method2(){

    }
    get method3(){

    }

}
Enter fullscreen mode Exit fullscreen mode

inside of the constructor() method we use the this keyword. In the context of a class this refers to an instance of that class.

What then is an Instance?
An instance is an object that contains the property names and methods of a class, but with unique property values.

What are Methods?
Class methods and getter syntax is the same as it is for objects except you cannot include commas between methods. But how do we call this methods;

Method calls:
Before a method is called the instance of the class is created and assigned to a variable.

const lucky = new Dog('lucky','American Bulldog');
Enter fullscreen mode Exit fullscreen mode

The syntax for calling methods and getters on an instance is the same as calling them on an object, which is done by appending the instance with a period, then the property or method name. For methods, you must also include the opening and closing parenthesis. But for getters you don't need to. In the example below we would show this;

lucky.method1() //when we are calling methods
lucky.method3 //when we are calling getters, no parenthesis
Enter fullscreen mode Exit fullscreen mode

A full example of a class, constructors and method calls we can see below;

class Dog{
    constructor(name,breed){
        this._name = name; //when we are using getter and setters we add underscore to our properties.
        this._breed = breed;
        this._behaviour = 0;
    }
    get name(){
        return this._name;
    }
    get breed(){
        return this._breed;
    }
    get behaviour(){
        return this._behaviour;
    }
    incrementBehaviour(){
        this._behaviour++;
    }
}

let lucky = new Dog('lucky','American Bulldog');
console.log(lucky.name)//returns the dogs name
console.log(lucky.breed)//returns the dogs breed
console.log(lucky.behaviour)//return the value of behaviour
lucky.incrementBehaviour(); //increases the count for the behaviour property
console.log(lucky.behaviour)//returns the new value after incrementing.
Enter fullscreen mode Exit fullscreen mode

But what if your daycare starts growing and we start accepting other pets like cats, etc. Are we going to be creating different classes for each of them?

class Cat{
    constructor(name,breed){
        this._name = name; //when we are using getter and setters we add underscore to our properties.
        this._breed = breed;
        this._behaviour = 0;
    }
    get name(){
        return this._name;
    }
    get breed(){
        return this._breed;
    }
    get behaviour(){
        return this._behaviour;
    }
    incrementBehaviour(){
        this._behaviour++;
    }
}

let kitty = new Dog('Kiity','American Bulldog');
console.log(kitty.name)//returns the dogs name
console.log(kitty.breed)//returns the dogs breed
console.log(kitty.behaviour)//return the value of behaviour
kitty.incrementBehaviour(); //increases the count for the behaviour property
console.log(kitty.behaviour)//returns the new value after incrementing.
Enter fullscreen mode Exit fullscreen mode

That would also mean us repeating codes, something we were avoiding initially, but how do we solve this problem, this is where we use a concept in Es6 classes called Inheritance.

Inheritance:
When multiple classes share properties or methods they become candidates for inheritance. A tool developers use to decrease the amount of code they need to write.
With inheritance, you can create a parent class (also known as a Super Class) with properties and methods that multiple child classes (known as sub classes) share. The child classes inherit the properties and methods from their parent class.

class subclass illustration

In our example we would need to create a parent class Animal, that other classes like cat and dog would inherit from.

class Animal{
    constructor(name,breed){
        this._name = name; //when we are using getter and setters we add underscore to our properties.
        this._breed = breed;
        this._behaviour = 0;
    }
    get name(){
        return this._name;
    }
    get breed(){
        return this._breed;
    }
    get behaviour(){
        return this._behaviour;
    }
    incrementBehaviour(){
        this._behaviour++;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now creating the Dog class to inherit from the parent class Animal;

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

class Cat extends Animal{
    constructor(name,breed,size){
        super(name,breed);
        this._size = size;
    }
    get size(){
        return this._size;
    }
}

let lucky = new Dog('lucky','Caucasian','barks');
console.log(lucky.name); //logs lucky
console.log(lucky.breed); //logs caucasian
console.log(lucky.sound); //logs bark
console.log(lucky.behaviour); //logs current value
lucky.incrementBehaviour(); //increments behaviour
console.log(lucky.behaviour); //logs new value

let kitty = new Cat('kitty','dontknow','4kg');
console.log(kitty.name); //logs kitty
console.log(kitty.breed); //logs dontknow
console.log(kitty.size); //logs 4kg
console.log(kitty.behaviour); //logs current value
kitty.incrementBehaviour(); //increments behaviour
console.log(kitty.behaviour); //logs new value
Enter fullscreen mode Exit fullscreen mode

In the example above, we created new classes that extends the Animal class, lets pay special attention to our new keywords, extends and super;

  1. Extends keyword makes the method of the animal class available inside the cat or dog class.
  2. The constructor, called when you create a new cat or dog object, accepts three arguments(name,breed and sound or size).
  3. The super keyword calls the constructor of the parent class. In this case, super(name,breed) passes the new argument of the cat class to the constructor of the animal class. When the animal constructor runs it, it sets this._name and this._breed = name and breed respectively; for new cat or dog instance.
  4. sound and size are new properties unique to dog and cat respectively,so we set it in the constructor.

Note:
We call super on the first line of the constructor before calling this, just so as to avoid getting JavaScript's reference error thrown.
When we call extends in a class declaration, all of the parent methods become available to the child class.

SUmmary:

  1. Classes are templates for objects
  2. JavaScript calls the constructor method when we create a new instance of a class.

Top comments (1)

Collapse
 
olivermensahdev profile image
Oliver Mensah

This piece gives the great overview classes in JavaScript and I love it. From the excerpt, "When we call extends in a class declaration, all of the parent methods become available to the child class", I think it is related to JavaScript only where there are only public access modifiers to methods and properties. In some languages, this might not be true. I think it would be great to tell the audience who might be starting to program and have no idea about these access modifiers.