Search Knowledge

© 2026 LIBREUNI PROJECT

Modern JavaScript & Ecosystem / Object-Oriented JavaScript

Modern OOP: Classes and Encapsulation

The Class Abstraction

ECMAScript 2015 introduced the class syntax to provide a more familiar organizational structure for developers coming from languages like Java or C++. However, as previously established, this is an abstraction over the prototype chain. Classes in JavaScript are essentially special functions.

Structure of a Class

A class definition typically includes a constructor, methods, and optionally, static members.

class Spacecraft {
  constructor(name, range) {
    this.name = name;
    this.range = range;
  }

  // Prototype method
  launch() {
    return `${this.name} is entering orbit.`;
  }

  // Static method (on the class itself, not instances)
  static getManufacturer() {
    return "Void Dynamics Corp.";
  }
}

Static Members and the this Context

Static methods and properties are defined on the class itself rather than on the instance. Inside a static method, this refers to the class constructor, not an object instance. Static members are often used for utility functions or factory methods.

Private Fields and Encapsulation

Historically, JavaScript developers used a convention of prefixing properties with an underscore (e.g., _secret) to signal that they should be treated as private. However, this was purely a convention and did not prevent external access.

Modern JavaScript (ES2022+) supports Private Class Fields using the # prefix. These fields are truly encapsulated; they cannot be accessed or modified from outside the class body, even through property indexing.

javascript
1class SecureVault {
2 #accessCode; // Private field
3 
4 constructor(code) {
5 this.#accessCode = code;
6 }
7 
8 checkCode(attempt) {
9 return attempt === this.#accessCode;
10 }
11}
12 
13const vault = new SecureVault(1234);
14console.log(vault.checkCode(1234)); // true
15try {
16 console.log(vault.#accessCode); // Throws SyntaxError
17} catch (e) {
18 console.log("Access Denied: Private Field.");
19}

Inheritance with extends and super

The extends keyword allows a class to inherit from another class. The super() call inside the constructor is mandatory before accessing this, as it initializes the parent class and binds the instance.

class Rocket extends Spacecraft {
  constructor(name, range, fuelType) {
    super(name, range); // Call parent constructor
    this.fuelType = fuelType;
  }

  // Method overriding
  launch() {
    return `${super.launch()} Igniting ${this.fuelType} boosters.`;
  }
}

Getters and Setters

Classes support get and set keywords to define computed properties or interpose logic during property access/assignment. This allows for validation and transformation while maintaining a property-like interface.

What happens if you attempt to access a private field (e.g., #data) from outside the class where it is defined?

Performance of Classes

While classes provide a clean syntax, they carry the same performance characteristics as prototypal inheritance. The method lookup still involves traversing the prototype chain. However, modern engines optimize class-based structures very effectively because the fixed shape of class instances allows for stable inline caches and optimized machine code generation.