[JavaScript] Mastering ES6 Class Syntax - Comprehensive Learning of Class Declaration, Initialization, Method Definition, and Inheritance

JavaScript's class syntax was introduced in ES6 (ES2015). Previously, object-oriented programming in JavaScript was primarily achieved using functions and prototypes. However, with the introduction of the class syntax, object-oriented programming has become more intuitive and clearly articulated.

Rationale and Advantages of Using Classes

  • Intuitiveness: The class syntax in JavaScript is similar to classes in other object-oriented languages, making it more familiar and easier to understand for developers.
  • Reusability: Leveraging classes and inheritance can significantly enhance code reusability.
  • Modularity: The structure of the code can be managed in a more organized manner.

Basic Syntax

Declaring a Class

In JavaScript, a class is declared using the class keyword.

javascript
class Person {}

Initialization Using the Constructor Method

The constructor method is a special method called when an instance of a class is created. It allows for the initial state of the instance to be set.

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

In the code above, the Person class possesses two attributes: name and age. When an instance of this class is created using the new keyword, the constructor method gets invoked, and the provided name and age are set to the instance.

javascript
const JohnDoe = new Person('John Doe', 25);
console.log(JohnDoe.name);  // John Doe

Method Definition

Within a class, functions can be defined as methods. These methods can be invoked on instances of the class.

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

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

Instance Methods vs. Static Methods

  • Instance Methods: Methods that are invoked on instances of the class. The introduce method above is an example.
  • Static Methods: Defined using the static keyword, these methods are invoked on the class itself without creating an instance.
javascript
class Person {
  static populationCount() {
    console.log('There are billions of humans.');
  }
}
Person.populationCount();  // There are billions of humans.

The earlier defined Person class's introduce method can be called as follows:

javascript
const JohnDoe = new Person('John Doe', 25);
JohnDoe.introduce();  // My name is John Doe, and I am 25 years old.

Static method populationCount can be directly invoked using the class name without creating an instance.

javascript
Person.populationCount();  // There are billions of humans.

Inheritance and Extension

In JavaScript, inheritance in classes denotes a mechanism where attributes and methods from an existing class are passed on to a new class. This promotes code reusability and facilitates the establishment of hierarchical relationships between classes.

Understanding the Concept of Inheritance

Inheritance in JavaScript classes is implemented using the extends keyword.

javascript
class Animal {
  makeSound() {
    console.log('Animal sound');
  }
}

class Dog extends Animal {

}

By using inheritance, the child class inherits all the attributes and methods of the parent class. In the example above, the Dog class inherits all methods and attributes from the Animal class.

Code Reusability through Inheritance

Employing inheritance allows the definition of common logic or data structures in the parent class, while only adding unique features or attributes to the child class. This reduces code duplication, enhancing development efficiency and ease of maintenance.

Method Overriding

A child class can redefine a parent class method with the same name. This is known as method overriding. The overridden method replaces the original method from the parent class.

javascript
class Animal {
  makeSound() {
    console.log('Animal sound');
  }
}

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

const Fido = new Dog();
Fido.makeSound();  // Bark

Invoking Parent Methods Using the Super Keyword

The super keyword allows for the invocation of a parent class's method from within a child class.

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

const Fido = new Dog();
Fido.makeSound();  
// Animal sound
// Bark

Constructor Overriding

In derived classes, it is possible to override the constructor of the base class. However, if super is not invoked within the derived class's constructor, an error will occur.

By using the super keyword in the derived class's constructor, we can call the base class's constructor. This facilitates any necessary initialization operations in the base class.

javascript
class Animal {
  constructor(name) {
    this.name = name;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}

const doggy = new Dog('doggy', 'Poodle');
console.log(doggy.name);   // doggy
console.log(doggy.breed); // Poodle

Access Modifiers

We'll delve into access modifiers used in JavaScript classes to restrict access to data and methods.

Public, Private, Protected

Access modifiers determine the accessibility of class members (attributes and methods). They help in preserving the encapsulation principle of object-oriented programming by concealing the internal implementation of a class or by allowing restricted access to specific members.

  • Public: By default, all members are public, meaning they can be accessed from anywhere.
  • Private: Members starting with a # symbol or an underscore (_) are private and can only be accessed within the class.
  • Protected: Currently, JavaScript doesn't officially support the protected access modifier. However, using the underscore (_) convention effectively emulates protected, implying that it can be accessed within the class and its subclasses.

Use of underscore (_) and # for Private Member Variables and Methods

javascript
class Example {
  _protectedMember = "Can be used like protected.";
  #privateMember = "This is a private variable.";

  _protectedMethod() {
    console.log("This method can be utilized as if it's protected.");
  }

  #privateMethod() {
    console.log("This is a private method.");
  }
}

Getter and Setter Methods

Getter and Setter methods encapsulate the operations of accessing and modifying an object's attributes. This ensures safe access to the object's internal data or executes specific logic.

Definition and Usage of Getter and Setter Methods

javascript
class Person {
  constructor(name) {
    this._name = name;
  }

  get name() {
    return this._name;
  }

  set name(value) {
    this._name = value;
  }
}

const John = new Person("John");
console.log(John.name); // John
John.name = "Jane";
console.log(John.name); // Jane

Static Members

Static members belong to the class itself and not to any instance. They are used when creating attributes or methods shared across the class.

Defining Static Variables and Methods at the Class Level

javascript
class Math {
  static PI = 3.141592;

  static circleArea(radius) {
    return this.PI * radius * radius;
  }
}

console.log(Math.PI);       // 3.141592
console.log(Math.circleArea(5)); // approximately 78.5398

Differences and Applications of Static Methods and Instance Methods

Static methods are invoked at the class level and are utilized when operations unrelated to any instance's specific state are needed. On the other hand, instance methods operate based on an object's internal state, accessing or modifying the object's data.


The myriad features related to classes in JavaScript effectively assist in implementing the object-oriented programming paradigm. Leveraging these features judiciously enhances the reusability, extensibility, and maintainability of code. It is hoped that you will harness the power of these robust JavaScript class features to conduct efficient programming.


© Copyright 2023 CLONE CODING