In this section, we will delve into the concepts of classes and object-oriented programming (OOP) in JavaScript. This is an advanced topic that builds on your understanding of objects and functions. By the end of this module, you will be able to create and use classes, understand inheritance, and apply OOP principles in your JavaScript code.

Key Concepts

  1. Classes: Templates for creating objects.
  2. Constructor: A special method for initializing new objects.
  3. Methods: Functions defined within a class.
  4. Inheritance: Mechanism to create a new class from an existing class.
  5. Encapsulation: Bundling data and methods that operate on the data within one unit.
  6. Polymorphism: Ability to process objects differently based on their data type or class.

  1. Introduction to Classes

What is a Class?

A class in JavaScript is a blueprint for creating objects with predefined properties and methods. Classes are introduced in ES6 and provide a more structured and syntactically cleaner way to work with objects and inheritance.

Syntax

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

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

// Creating an instance of the Person class
const person1 = new Person('Alice', 30);
person1.greet(); // Output: Hello, my name is Alice and I am 30 years old.

Explanation

  • class Person: Defines a new class named Person.
  • constructor(name, age): A special method for initializing new objects. It sets the name and age properties.
  • greet(): A method that logs a greeting message to the console.
  • new Person('Alice', 30): Creates a new instance of the Person class.

  1. Inheritance

Inheritance allows a class to inherit properties and methods from another class. This promotes code reuse and a hierarchical class structure.

Syntax

class Employee extends Person {
  constructor(name, age, jobTitle) {
    super(name, age); // Calls the constructor of the parent class
    this.jobTitle = jobTitle;
  }

  work() {
    console.log(`${this.name} is working as a ${this.jobTitle}.`);
  }
}

// Creating an instance of the Employee class
const employee1 = new Employee('Bob', 25, 'Software Developer');
employee1.greet(); // Output: Hello, my name is Bob and I am 25 years old.
employee1.work();  // Output: Bob is working as a Software Developer.

Explanation

  • class Employee extends Person: Defines a new class Employee that inherits from Person.
  • super(name, age): Calls the constructor of the parent class (Person).
  • work(): A method specific to the Employee class.

  1. Encapsulation

Encapsulation is the concept of bundling data and methods that operate on the data within one unit, typically a class. It also involves restricting direct access to some of the object's components.

Example

class BankAccount {
  #balance; // Private field

  constructor(initialBalance) {
    this.#balance = initialBalance;
  }

  deposit(amount) {
    this.#balance += amount;
    console.log(`Deposited: $${amount}. New Balance: $${this.#balance}`);
  }

  withdraw(amount) {
    if (amount <= this.#balance) {
      this.#balance -= amount;
      console.log(`Withdrew: $${amount}. New Balance: $${this.#balance}`);
    } else {
      console.log('Insufficient funds');
    }
  }

  getBalance() {
    return this.#balance;
  }
}

// Creating an instance of the BankAccount class
const account = new BankAccount(1000);
account.deposit(500); // Output: Deposited: $500. New Balance: $1500
account.withdraw(200); // Output: Withdrew: $200. New Balance: $1300
console.log(account.getBalance()); // Output: 1300

Explanation

  • #balance: A private field, accessible only within the class.
  • deposit(amount) and withdraw(amount): Methods to modify the balance.
  • getBalance(): A method to access the balance.

  1. Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common superclass. It is achieved through method overriding.

Example

class Animal {
  makeSound() {
    console.log('Some generic animal sound');
  }
}

class Dog extends Animal {
  makeSound() {
    console.log('Bark');
  }
}

class Cat extends Animal {
  makeSound() {
    console.log('Meow');
  }
}

const animals = [new Animal(), new Dog(), new Cat()];

animals.forEach(animal => animal.makeSound());
// Output:
// Some generic animal sound
// Bark
// Meow

Explanation

  • makeSound(): A method in the Animal class.
  • Dog and Cat classes override the makeSound() method.
  • animals.forEach(animal => animal.makeSound()): Demonstrates polymorphism by calling the overridden methods.

Practical Exercises

Exercise 1: Create a Class

Create a class Car with properties make, model, and year. Add a method displayInfo() that logs the car's details.

class Car {
  constructor(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
  }

  displayInfo() {
    console.log(`Car: ${this.make} ${this.model}, Year: ${this.year}`);
  }
}

// Solution
const car1 = new Car('Toyota', 'Corolla', 2020);
car1.displayInfo(); // Output: Car: Toyota Corolla, Year: 2020

Exercise 2: Implement Inheritance

Create a class ElectricCar that inherits from Car and adds a property batteryLife. Add a method displayBatteryLife() that logs the battery life.

class ElectricCar extends Car {
  constructor(make, model, year, batteryLife) {
    super(make, model, year);
    this.batteryLife = batteryLife;
  }

  displayBatteryLife() {
    console.log(`Battery Life: ${this.batteryLife} hours`);
  }
}

// Solution
const electricCar1 = new ElectricCar('Tesla', 'Model S', 2021, 24);
electricCar1.displayInfo(); // Output: Car: Tesla Model S, Year: 2021
electricCar1.displayBatteryLife(); // Output: Battery Life: 24 hours

Summary

In this section, we covered the fundamentals of classes and object-oriented programming in JavaScript. We learned about:

  • Defining and using classes.
  • Inheritance and how to extend classes.
  • Encapsulation and private fields.
  • Polymorphism and method overriding.

These concepts are crucial for writing clean, maintainable, and scalable JavaScript code. In the next module, we will explore more advanced topics related to objects and functions.

JavaScript: From Beginner to Advanced

Module 1: Introduction to JavaScript

Module 2: Control Structures

Module 3: Functions

Module 4: Objects and Arrays

Module 5: Advanced Objects and Functions

Module 6: The Document Object Model (DOM)

Module 7: Browser APIs and Advanced Topics

Module 8: Testing and Debugging

Module 9: Performance and Optimization

Module 10: JavaScript Frameworks and Libraries

Module 11: Final Project

© Copyright 2024. All rights reserved