JavaScript Classes: A Modern Approach to Object-Oriented Programming

With the introduction of ES6, JavaScript provided the class syntax, making it easier and more intuitive to create object blueprints, similar to traditional object-oriented programming languages like C++ or Java.

In this blog, we'll explore JavaScript classes with a simple example and dive into their core concepts.


Example: Creating a Person Class

Let's start by creating a Person class that defines two properties (name and age) and a method (greet):

// Define a class named 'Person'
class Person {
  // Constructor to initialize properties
  constructor(name, age) {
    this.name = name; // Assign 'name' to the instance
    this.age = age; // Assign 'age' to the instance
  }

  // Define a method to display a greeting message
  greet() {
    console.log(
      `Hello, my name is ${this.name} and I am ${this.age} years old.`
    );
  }
}

// Create instances of the 'Person' class
let person1 = new Person("Jack", 30);
let person2 = new Person("Tina", 33);

// Call the 'greet' method on both instances
person1.greet();
person2.greet();

Output

Hello, my name is Jack and I am 30 years old.
Hello, my name is Tina and I am 33 years old.

Breaking Down the Example

1. Defining a Class

We use the class keyword to define a blueprint for objects. The class includes:

  • Properties: Variables that hold data specific to the object (e.g., name, age).
  • Methods: Functions that define the behavior of the object (e.g., greet()).

In our example, the Person class encapsulates the properties name and age and provides a greet method for interaction.

2. Class Constructor

The constructor is a special method used to initialize new objects. It's automatically called when an object is created using the new keyword.

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

Here:

  • this.name refers to the name property of the current object.
  • this.age refers to the age property of the current object.
  • name and age are parameters passed to the constructor when creating an object.

3. Creating Instances

To create an instance of a class, use the new keyword:

let person1 = new Person("Jack", 30);
let person2 = new Person("Tina", 33);

Each instance has its own unique values for the name and age properties.

4. Calling Methods

To invoke a method, use dot notation:

person1.greet(); // Hello, my name is Jack and I am 30 years old.
person2.greet(); // Hello, my name is Tina and I am 33 years old.

The method accesses the instance-specific properties (this.name and this.age) to generate the greeting message.


Additional Features of Classes

Static Methods

Static methods are defined using the static keyword and can be called directly on the class without creating an instance:

class MathUtils {
  static add(a, b) {
    return a + b;
  }
}

console.log(MathUtils.add(5, 7)); // Output: 12

Inheritance

Classes can extend other classes using the extends keyword, enabling code reuse and specialization:

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.`
    );
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // Call the parent class constructor
    this.grade = grade;
  }

  study() {
    console.log(`${this.name} is studying in grade ${this.grade}.`);
  }
}

let student = new Student("Alice", 14, 9);
student.greet(); // Hello, my name is Alice and I am 14 years old.
student.study(); // Alice is studying in grade 9.

Getters and Setters

You can define getter and setter methods to control how properties are accessed or modified:

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  // Getter for area
  get area() {
    return this.width * this.height;
  }

  // Setter to ensure width is positive
  set width(value) {
    if (value <= 0) {
      console.error("Width must be positive!");
    } else {
      this._width = value;
    }
  }

  get width() {
    return this._width;
  }
}

let rect = new Rectangle(5, 10);
console.log(rect.area); // Output: 50
rect.width = -3; // Output: Width must be positive!

Why Use Classes?

  1. Cleaner Syntax: Classes make it easier to define and manage object blueprints compared to prototype-based inheritance.
  2. Encapsulation: Classes group properties and methods into a single structure, improving code readability and maintainability.
  3. Inheritance: Classes enable code reuse through inheritance, simplifying the creation of specialized objects.
  4. Modern Features: Static methods, getters/setters, and other ES6+ features add flexibility and power to JavaScript classes.

Conclusion

JavaScript classes provide a powerful yet simple way to work with object-oriented programming in modern JavaScript. Whether you're building simple objects or complex hierarchies, classes offer a structured and maintainable approach. By understanding features like inheritance, static methods, and getters/setters, you can unlock the full potential of JavaScript's class syntax.

Learn More

  1. Unit Testing for Express API: A Step-by-Step Guide
  2. A practical guide to data collection with OpenTelemetry, Prometheus and Grafana
  3. Flask and SQLAlchemy: Better Data Management

Please let me know if there's anything else I can add or if there's any way to improve the post. Also, leave a comment if you have any feedback or suggestions.

Discussions

Up next