Classes in JavaScript

Classes in JavaScript

This article explains classes in JavaScript.

YouTube Video

Classes in JavaScript

In JavaScript, a class incorporates the concept of object-oriented programming and serves as a blueprint for objects. With classes, you can succinctly define the properties and methods of an object, improving reusability and code organization. Class syntax was introduced in JavaScript with ES6.

Class Definition

A class is defined with the class keyword and is typically initialized with a method called a constructor.

 1class Person {
 2    // Constructor method (called when the class is instantiated)
 3    constructor(name, age) {
 4        this.name = name; // Property definition
 5        this.age = age;
 6    }
 7
 8    // Method definition
 9    greet() {
10        return `Hello, my name is ${this.name}`;
11    }
12}
13
14// Instantiation of the class
15const alice = new Person("Alice", 25);
16console.log(alice.greet()); // Hello, my name is Alice
  • We define a class with class Person.
  • The constructor is a special method that is automatically called when an object is created.
  • The this keyword refers to the instance (object) of the class within the class.

Class Properties and Methods

A class can define properties and methods. Properties represent the attributes of an object, and methods represent the functions it has.

 1class Car {
 2    constructor(brand, model) {
 3        this.brand = brand;
 4        this.model = model;
 5    }
 6
 7    // Method definition
 8    drive() {
 9        console.log(`Driving a ${this.brand} ${this.model}`);
10    }
11}
12
13const car1 = new Car("Toyota", "Corolla");
14car1.drive(); // Driving a Toyota Corolla

In this example, a Car class is declared with brand and model properties and a drive method.

Class Inheritance

Classes can inherit from other classes. By using inheritance, you can create a new class based on an existing class and add additional functionality to it.

 1class Animal {
 2    constructor(name) {
 3        this.name = name;
 4    }
 5
 6    speak() {
 7        console.log(`${this.name} makes a noise`);
 8    }
 9}
10
11// Inherit from the Animal class
12class Dog extends Animal {
13    constructor(name, breed) {
14        super(name); // Call the constructor of the parent class (Animal)
15        this.breed = breed;
16    }
17
18    // Override the method
19    speak() {
20        console.log(`${this.name} barks`);
21    }
22}
23
24const dog = new Dog("Rex", "German Shepherd");
25dog.speak(); // Rex barks

In this example, the Dog class inherits from the Animal class.

  • The extends keyword is used to inherit from the Animal class.
  • In the constructor of the Dog class, super() is used to call the constructor of the parent class. This allows you to inherit the initialization process of the parent class.
  • Within the inherited class, you can override the methods of the parent class. In this example, instead of "Rex makes a noise", "Rex barks" is displayed.

Static Methods

When you define a static method within a class, the method is associated with the class itself. Static methods can be called without being instantiated.

1class MathUtils {
2    // Static method
3    static add(a, b) {
4        return a + b;
5    }
6}
7
8console.log(MathUtils.add(5, 10)); // 15

In this example, the MathUtils class has a static method add defined.

  • The static keyword is used to define a static method.
  • Static methods do not belong to class instances and can be called directly from the class itself.

Getters and Setters

By defining getters and setters in a class, you can encapsulate the retrieval and setting of properties.

 1class Rectangle {
 2    constructor(width, height) {
 3        this.width = width;
 4        this.height = height;
 5    }
 6
 7    // Getter
 8    get area() {
 9        return this.width * this.height;
10    }
11
12    // Setter
13    set widthValue(newWidth) {
14        this.width = newWidth;
15    }
16}
17
18const rect = new Rectangle(10, 20);
19console.log(rect.area); // 200
20
21rect.widthValue = 15;
22console.log(rect.area); // 300

In this example, the Rectangle class defines an area getter and a widthValue setter.

  • Getter (get) is called when retrieving the value of a property.
  • Setter (set) is called when setting the value of a property.

Class Syntax Sugar

In JavaScript, class syntax is internally implemented using constructor functions and prototypes. Class syntax is syntactic sugar for writing these more concisely.

 1// Example without using class syntax
 2function Person(name, age) {
 3    this.name = name;
 4    this.age = age;
 5}
 6
 7Person.prototype.greet = function() {
 8    return `Hello, my name is ${this.name}`;
 9};
10
11const person = new Person("Alice", 25);
12console.log(person.greet()); // Hello, my name is Alice

In this example, a constructor function Person is defined, and the greet method is defined using a prototype.

Handling this

The this keyword inside a class refers to the instance of that class. However, when dealing with this in class methods, you need to be aware that its behavior can vary depending on the scope. Problems may arise particularly when using methods as callback functions.

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13setTimeout(counter.increment, 1000); // NaN
14// NaN, since this.count is undefined, it becomes NaN after incrementing.

In such cases, when passed as a callback to setTimeout, the reference this points to may change. To avoid this problem, it is recommended to either fix this using the bind method or use arrow functions.

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13
14// When using bind
15setTimeout(counter.increment.bind(counter), 1000);
16
17// When using an arrow function
18setTimeout(() => counter.increment(), 2000);

Summary

  • Classes are used as blueprints for creating objects, defining properties and methods.
  • You can use inheritance to extend a class, utilizing object-oriented concepts.
  • Static methods belong to the class itself and can be used without creating an instance.
  • You can encapsulate properties using getters and setters.
  • JavaScript's class syntax is syntax sugar and internally uses prototype-based inheritance.

By using classes, you can handle object-oriented programming more naturally, and improve code reusability and maintainability.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video