# JavaScript Classes

JavaScript Classes are a powerful feature of the language that allows us to create reusable and modular code. In this blog post, let us see why you should use classes and some examples using the most important concepts of class syntax.

## Why use classes?

Classes are a way of defining a blueprint for creating objects that share the same properties and methods. Objects are instances of classes that can store data and perform actions. For example, you can define a class called Animal that has properties like name, age, and color, and methods like speak and eat. Then you can create objects like dog, cat, and bird that are instances of the Animal class and inherit its properties and methods.

Classes make code more organized, readable, and maintainable. They also enable inheritance, which is a mechanism that allows one class to extend another class and reuse its code. For example, you can define a class called Dog that extends the Animal class and adds some specific properties and methods for dogs, like breed and bark. Then you can create objects like labrador, poodle, and husky that are instances of the Dog class and inherit both the Animal and Dog properties and methods.

## How to write classes?

To define a class in JavaScript, we use the class keyword followed by the name of the class. The name should start with a capital letter and follow the camelCase convention. For example:

```javascript
class Animal {
 // class body 
}
```

To create an object from a class, we use the new keyword followed by the name of the class and parentheses. For example:

`let dog = new Animal();`

## The constructor method

The constructor method is a special method that is executed when a new object is created from a class. It is used to initialize the object with some initial values or perform some actions. The constructor method is optional, but if it is defined, it must have the name constructor. For example:

```javascript
class Animal { 
    constructor(name, age, color) {
        this.name = name;
        this.age = age; 
        this.color = color;
    }
}

let dog = new Animal("Max", 3, "brown");
```

The `this` keyword refers to the current object that is being created. The parameters of the constructor method are passed as arguments when creating a new object.

## The `getter` and `setter` methods

The `getter` and `setter` methods are special methods that allow us to access and modify the properties of an object in a controlled way. They are also optional, but if they are defined, they must have the keywords get and set before their names. For example:

```javascript
class Animal { 
    constructor(name, age, color) { 
        this.name = name; 
        this.age = age; 
        this.color = color; 
    }

    get name() { 
        return this.name; 
    }

    set name(newName) { 
        this.name = newName;
    } 
}

let dog = new Animal("Max", 3, "brown");
console.log(dog.name);
// Max dog.name = "Rex"; console.log(dog.name); // Rex
```

The `getter` method returns the value of the property, while the setter method assigns a new value to the property. They can also be used to perform some validation or computation on the property values.

## The `extends` keyword

The extends keyword is used to create a subclass that inherits from another class (the superclass). The subclass can access and override the properties and methods of the superclass, as well as add its own specific properties and methods. For example:

```javascript
class Dog extends Animal { 
    constructor(name, age, color, breed) { 
        super(name, age, color); // call the superclass constructor 
        this.breed = breed; // add a new property 
    }

    bark() { 
        console.log(this.name + " says woof!"); // add a new method 
    }

    speak() { 
        super.speak(); // call the superclass method 
        console.log(this.name + " is a " + this.breed); // override the superclass method
    } 
}

let labrador = new Dog("Lola", 2, "yellow", "Labrador"); 
labrador.bark(); 
// Lola says woof! 
labrador.speak(); 
// Lola says hello! Lola is a Labrador
```

The `super` keyword is used to refer to the superclass and call its constructor or methods.

## Private and public fields

Private and public fields are a way of defining properties that are either accessible only within the class (private) or outside the class (public). Private fields are prefixed with a hash sign (#), while public fields have no prefix. For example:

```javascript
class Animal { 
    #name; // private field 
    age; // public field

    constructor(name, age) { 
        this.#name = name; 
        this.age = age; 
    }

    getName() { 
        return this.#name; // access private field within class 
    } 
}

let dog = new Animal("Max", 3); 
console.log(dog.age); 
// 3 
console.log(dog.#name); 
// SyntaxError: Private field '#name' must be declared in an enclosing class 
console.log(dog.getName()); 
// Max
```

Private fields are useful for hiding implementation details or protecting sensitive data from external access. Public fields are useful for exposing data or functionality to the outside world.

## Static methods and fields

Static methods and fields are methods and fields that belong to the class itself, not to the instances of the class. They are prefixed with the `static` keyword. For example:

```javascript
class Animal { 
    static planet = "Earth"; // static field

    static greet() { 
        console.log("Hello from " + this.planet); // static method 
    } 
}

console.log(Animal.planet); // Earth 
Animal.greet(); // Hello from Earth

let dog = new Animal(); 
console.log(dog.planet); // undefined 
dog.greet(); // TypeError: dog.greet is not a function
```

Static methods and fields are useful for defining constants or utility functions that are related to the class, but do not depend on the instances of the class.

## Static blocks

Static blocks are blocks of code that are executed only once when the class is defined. They are useful for initializing static fields or performing some actions that only need to be done once. They are enclosed by curly braces and preceded by the static keyword. For example:

```javascript
class Animal { 
    static planet = "Earth"; // static field

    static { // static block 
        console.log("Defining the Animal class"); 
        this.planet = this.planet.toUpperCase(); // modify static field 
    }

    static greet() { 
        console.log("Hello from " + this.planet); // static method 
    }
}

console.log(Animal.planet); // EARTH 
Animal.greet(); // Hello from EARTH

let dog = new Animal(); 
console.log(dog.planet); // undefined 
dog.greet(); // TypeError: dog.greet is not a function
```

## Conclusion

In this blog post, we have learned why and how to use classes in JavaScript. Classes are a powerful feature that allow us to create reusable and modular code, enable inheritance, and control access and visibility of properties and methods. We have also covered some important concepts of class syntax, such as constructor, getter and setter, extends, private and public fields, static methods and fields, and static blocks
