Week 4 - Class is in session
Tags: javascript, webdev, beginners, programming
Published: 2022-05-22 20:35:31

Within many programming languages, classes are the a common concept due to Object Orientated Programming being the dominant paradigm.

JavaScript is no different to other programming languages with its support of classes, however, its implementation of classes IS very different, which we will explore.

Following the previous posts, the main resource and supplementary resources are shown below, and are discussed at the latter end of the post.

- Main Resource - [LearnJavaScript.online](https://learnjavascript.online/)
- Supplementary Resource #1 - [StackOverflow Classical Inheritence vs Prototype Inheritence](https://stackoverflow.com/questions/19633762/classical-inheritance-vs-prototypal-inheritance-in-javascript#:~:text=Classical%20inheritance%20is%20limited%20to,also%20objects%20inheriting%20from%20prototypes.)
- Supplementary Resource #2 - [MDN JavaScript Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)

# What Was Learnt
JavaScript has a variety of ways of programming, procedural, functional, and object-orientated. 

Within JavaScript, object-orientated programming is developed through the creation of objects, which is achieved through the use of the curly bracer, as follows:

```
const myObject = {
    name: "Jack/eXit",
    language: "JavaScript"
};
```

The remainder of this blog post focuses on the Object Orientated Programming implementation of JavaScript. 

## Classes
However, the example above only provides us with a collection of data, instead we can create a more sophisticated version which has both data and functionality.

```
class Computer{
    constructor(name){
         this.name = name;
    }

    set name(value){
        this._name = value;
    }

    get name(){
        return `This is a ${this._name} computer`;
    }

    turnOn(){
       console.log("Turning on.... beep boop!");
    }

}

const myComputer = new Computer("Apple");
console.log(myComputer.name);
myComputer.turnOn();
```
This example has **alot** going on in it, and will be broken down in the following sections. 

### Constructors
Within a class, a constructor is a way of binding user or computer supplied content to a class, for example, a persons name, character id, character level, postal address, bank number, etc.

Within the example, the constructor takes the data of name, in this case, "Apple" and supplies it to the classes field, referred to as "this.name". We use "this" in a class to refer to the object. This is important when we have multiple versions of the class, also referred to as instantiated objects of class Computer.

### Getters and Setters
Getters and Setters are a great way of managing content within a class, along with constructors, as they help us manage data that is being set.

For example, if we have a value being set, e.g., an age. We might allow a user to set the name via a string or via a number. However, the setter can be used to parse the string into a number so that we remove any issues of using a string instead of a number.

The Getters also provide us a great way of returning data. Sometimes we might want to format the content that is being returned, like what was done in this example. Instead of returning just the string, we can also return some following text. 

### Methods
Methods provide our behaviour to our attributes (data). A method is just a Object Orientated Programming term for function. In this instance, we are using methods (functions) to give the class some behaviour that the user of the class can interact with. For example, because we are creating a class of Computer, we want to give it the behaviour of turning on. The method only prints a sentence out, however, it provides some dynamism to our objects in the future. If we wanted we could add a method for it to become sentient... but we shouldn't do that just yet!!!

## Inheritance
To provide further functionality so that we dont have to reinvent the wheel, JavaScript allows us to extend the class further, allowing us to define a computer, as well as sub-classes of computer, for example, mobile phones.

```
class Computer{
    constructor(name){
         this.name = name;
    }

    set name(value){
        this._name = value;
    }

    get name(){
        return `This is a ${this._name} computer`;
    }

    turnOn(){
       console.log("Turning on.... beep boop!");
    }

}

class Mobile extends Computer{
    constructor(name, type){
        super(name);
        this.type = type;
    }

    callSomeone(){
        console.log("Calling home to the mothership...");
    }
}

const myComputer = new Computer("Apple");
console.log(myComputer.name);
myComputer.turnOn();

const myMobile = new Mobile("eXits Phone", "Android");
myMobile.callSomeone();
```

This example extends the class of Computer by using the "extend" keyword. With this, we are able to **Inherit** the attributes and behaviours of the inherited class or parent class. 

Within the constructor of mobile, we can define new attributes such as the type of phone as shown via:

```
this.type = type;
```

but we can also use the "super" keyword:

```
super(name);
```

The "super" keyword is important as it allows us to inherit the attributes of the parent class, but also allows a developer to pass data back into the parent class, to reduce the amount of typing your fingers have to do!

**HOWEVER** while we see classes and the inheritance of its parent class via the `extend` keyword, the class functionality actually boils back to a function. This is what is called syntactic sugar, a term, which means that it makes life easier for us as developers to write and manage our code!!!

The next section discusses further the purpose of why `class` and `extend` are considered "syntactic sugar" and how the `extend` keyword truly inherits its parents behaviours and attributes.

## Prototype
As the introduction to this post discusses, JavaScript implements classes slightly differently to other languages. This is down to  the Prototype Chain, which is how classes **inherit** from one another.

Within every object, is a Prototype chain, which indicates the previous object that the current object inherits from, all the way back to the start of the chain, which will be the type **null**.

The image below, demonstrates the direction JavaScript reads a Prototype Chain (black arrows). From left to right, our classes we have defined in this blog post are illustrated in green, where the built in types are purple, going back to the Prototype type shown in red, and then terminating in the null type shown in grey.

![Direction of Reading for Prototype Chain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ptit3sn4t33rrdjxqg8c.png)

This is importance to understand as we can then verify the process by using the built in function `Object.getPrototypeOf();`. 

Using the above code (including the mobile class), we can output the following Prototype Chain to verify our diagram:

```
console.log(myMobile); // Mobile
console.log(Object.getPrototypeOf(myMobile)); // Computer
console.log(Object.getPrototypeOf(Object.getPrototypeOf(myMobile))); // Object
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(myMobile)))); // Prototype
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(myMobile))))); // null
```

By chaining our Prototypes together, JavaScript can create a very complex inheritance chain, as illustrated below, whereby each object inherits from its parent type and has its functionality as shown via the red lines allowing the object to access any method of behaviour its parents has without having to call the previous object directly.

![Inheritance Direction of Parent Object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ig03r2ad0jhh526x0rt.png)

## Further Theory
The theory behind of why JavaScript use Prototype-based inheritance is to manage the classical inheritance problem, which can be confusing to understand, however, this [StackOverflow](https://stackoverflow.com/questions/19633762/classical-inheritance-vs-prototypal-inheritance-in-javascript#:~:text=Classical%20inheritance%20is%20limited%20to,also%20objects%20inheriting%20from%20prototypes.) post elaborates further, which I urge you to read.

## Resource Review
The LearnJavaScript.online resource has been a great way of understanding the Object Orientated Programming paradigm from a JavaScript perspective. However, it is definitely worth supplementing the content with a wider reading around the theory of Classical Inheritance vs Prototype Inheritance just to understand what problem JavaScript is trying to solve in this instance. 

From further research, the supplementary [StackOverflow](https://stackoverflow.com/questions/19633762/classical-inheritance-vs-prototypal-inheritance-in-javascript#:~:text=Classical%20inheritance%20is%20limited%20to,also%20objects%20inheriting%20from%20prototypes.) post provides a clear comparison between the two theories and I strongly urge anyone to read it.

## Retrospective
- This weeks learning has been a lot of fun, It has definitely made me really understand the topic of inheritance more not only in JavaScript but also other languages like Java or C#. Therefore, I think graphical representations of different concepts are worth investing in.

## Sign Off
Thank you for reading this weeks post, this has been a really fun week!

Feel free to leave a comment if there is anything I have miss-typed or could try and simplify as it is a great way for me to compound my learning!

See you all next week :)

Jack/eXit