JavaScript Classes
Tags: javascript, beginners, oop, programming
Published: 2023-03-06 14:15:54

## What are classes? 

Classes are a template for creating objects. They encapsulate data with code to work on that data. In JavaScript, classes are defined using the class keyword, followed by the name of the class, and a set of curly braces.

```
class Person {

}
```
**note:** _Class names should always start with a capital letter_

The class uses something called a constructor which is used for creating and initializing an object instance of that class.

```
class Person {
    constructor(name, age, occupation, hobbies = []) {
       
   }
}

```

**note:** _the variables can take in default values as seen above for hobbies._

Within the constructor method, we use the **this** keyword, which references the newly created object instance. 

```
class Person {
    constructor(name, age, occupation, hobbies = []) {
        this.name = name
        this.age = age
        this.occupation = occupation
        this.hobbies = hobbies
   }
}
```

To create an instance of a class we use the **new** keyword and the name of the class.
```
let tatiana = new Person(
    'Tatiana',
    21,
    'Software Engineer',
    [
        "Reading",
        "guitar",
        "working out",
        "movie theater rat"
    ]
)
```

And once you console log the new instance you  should get:

```
Person {
  name: 'Tatiana',
  age: 21,
  occupation: 'Software Engineer',
  hobbies: [ 'Reading', 'guitar', 'working out', 'movie theater rat' ]
}
```

## Class & Instance Methods

Classes also use something called methods which is a function that is part of the class and performs an action for it. In javascript we have something called instance methods and static methods. An instance method is a method that is typically invoked on a given instance of the class stored in a variable. 

**Instance Method: **  
```
aboutMe() {
    console.log(
        `My name is ${this.name} I'm ${this.age} years old, and I work as a ${this.occupation}!`
    )
   }
```
In this example, I created a sentence using the variables from the constructor.

Which in return should give you:

```
My name is Tatiana I'm 21 years old, and I work as a Software Engineer!
```
when you call the method on the class instance like so: 

```
tatiana.aboutMe()
```
A static method is invoked directly on a class, not on the instance. And The syntax for a static method is the same as an instance except that their declarations start with the **static **keyword.

**Static Method:**
```
static getOccupations(...people) {
     return people.map(person => person.occupation)
   }
```
In this example, I'm using the static method to collect the occupation from each instance and return them in an array. You then use the static method by calling it on the class and passing in the instance methods.

```
let occupations = Person.getOccupations(tatiana, peachy)
console.log(occupations)
```
giving you: 
```
[ 'Software Engineer', 'Cafe Owner' ]
```

**Static Variables** 

 Along with the static methods, there is also something called _static variables_. Static variables are declared like the **static **keyword, followed by the variable name and value.

```
static peopleCount = 0;
```

Here's a usage example:
```
class Person {
    constructor(name, age, occupation, hobbies = []) {
        this.name = name
        this.age = age
        this.occupation = occupation
        this.hobbies = hobbies

    Person.peopleCount += 1;
   }
static peopleCount = 0;
}
```
In this example, I'm using the static variable to keep track of the number of Person instances being made. I should get the output of 2 after using the variable on the Person class.

```
console.log(Person.peopleCount)

//output 

2
```


**Putting it all together: **

```
class Person {
    constructor(name, age, occupation, hobbies = []) {
        this.name = name
        this.age = age;
        this.occupation = occupation
        this.hobbies = hobbies

        Person.peopleCount += 1
   }

   static peopleCount = 0;

   aboutMe() {
    console.log(
        `My name is ${this.name} I'm ${this.age} years old, and I work as a ${this.occupation}!`
    )
   }

   static getOccupations(...people) {
     return people.map(person => person.occupation)
   }
}

let tatiana = new Person(
    'Tatiana',
    21,
    'Software Engineer',
    [
        "Reading",
        "guitar",
        "working out",
        "movie theater rat"
    ]
)

let peachy = new Person (
    "Peachy",
    "22",
    "Cafe Owner",
    [
        "Reading",
        "drums",
        "guitar",
        "roller skating"
    ]
)

// instance methods
tatiana.aboutMe()
peachy.aboutMe()


// static methods
let occupations = Person.getOccupations(tatiana, peachy)
console.log(occupations)

// static variable
console.log(Person.peopleCount)
```

## Inheritance

Classes also have something called _inheritance_ which allows the properties and methods defined on a parent class to be available for objects created from classes that inherit from those parent classes. 

To implement inheritance we use the extends keyword to say that this class inherits from another class.

Example:

```
class Child extends Person {
    
}
```

**Super **

We then use something called the **super **keyword which is used to access properties on an object literal or class's Prototype, or invoke a superclass's constructor. 

The super keyword may appear as a "function call", and must be called before the this keyword is used. It calls the parent class's constructor and binds the parent class's public fields, after which the derived class's constructor can further access and modify this.

Example: 
```
class Child extends Person {
    constructor(firstName,age, occupation, hobbies, grade) {
    super(firstName, age, occupation, hobbies)
        this.grade = grade;
    }
}

let aisha  = new Child("A'isha", 9, "unemployed",["coloring", "dancing", "karate"], "5th" )
console.log(aisha)
```

giving us: 

```
Child {
  firstName: "A'isha",
  age: 9,
  occupation: 'unemployed',
  hobbies: [ 'coloring', 'dancing', 'karate' ],
  grade: '5th'
}
```

**note:** _make sure to add the super keyword, using inheritance w/o it will invoke a reference error._

```
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
```

## Conclusion 

Classes are a template for creating objects. They encapsulate data with code to work on that data. By using classes, you're ensuring that methods are only used on one set of data. Classes also provide an easy way of keeping the data members and methods together in one place which helps in keeping the program more organized.

## Helpful Resources 

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this