JavaScript Mastery: From Fundamentals to Modern ES2024+
OOP Architecture

Modern ES6+ Classes

While JavaScript remains prototypal under the hood, Classesprovide a structured, readable syntax for implementing Object-Oriented patterns. Modern updates (ES2022) have added true private fields and static initialization blocks, making them production-ready for enterprise architecture.

Encapsulation and Fields

Modern JavaScript classes support Public andPrivate fields. Unlike the old _variableconvention, fields prefixed with # are truly private at the engine level and cannot be accessed from outside the class body, providing real data integrity.

JAVASCRIPT
class ComputeEngine {
    // 1. Public Fields (ES2022)
    region = 'us-east-1';

    // 2. Private Fields (#) - Truly encapsulated
    #status = 'OFFLINE';

    constructor(id) {
        this.id = id;
    }

    // 3. Instance Method
    start() {
        this.#status = 'RUNNING';
        console.log(`Engine ${this.id} is ${this.#status}`);
    }

    // 4. Getter/Setter
    get status() { return this.#status; }
}

Static Initialization

Static methods and properties belong to the class itself, not its instances. ES2022 introduced Static Blocks, allowing for complex logic (like try/catch) when the class is first loaded by the engine.

JAVASCRIPT
class Database {
    static connectionLimit = 100;

    // ES2022 Static Initialization Block
    static {
        // Complex logic to run once when class is loaded
        try {
            const config = { env: 'PROD' };
            this.mode = config.env === 'PROD' ? 'SECURE' : 'DEV';
        } catch (e) {
            this.mode = 'SAFE';
        }
    }

    static connect() {
        console.log(`Connecting in ${this.mode} mode...`);
    }
}

The Super Mechanism

Inheritance allows a class to share behavior from a parent. The extends keyword sets up the prototype chain, and super() calls the parent constructor. Crucially, you cannot use this in a child constructor untilsuper() has been called.

JAVASCRIPT
class BaseAPI {
    constructor(endpoint) {
        this.endpoint = endpoint;
    }
    fetch() { console.log('Base Fetch'); }
}

class UserAPI extends BaseAPI {
    constructor(endpoint, token) {
        // Must call super() before accessing 'this'
        super(endpoint);
        this.token = token;
    }

    // Overriding while calling parent
    fetch() {
        super.fetch();
        console.log('User Auth Header Applied');
    }
}

Performance Considerations

Under the hood, class methods are added to the .prototype. This makes them highly memory efficient as thousands of instances can share a single function reference. However, using arrow functions as fields creates a new function for every instance.

JAVASCRIPT
// --- Performance Perspective ---

class HeavyObject {
    // ❌ Anti-pattern: Creating methods inside constructor
    constructor() {
        this.log = () => console.log('Inefficient');
    }

    // ✅ Best practice: Method on prototype
    log() {
        console.log('Efficient');
    }
}

/* 
   Note: Field initializers (like click = () => {}) 
   are added to the instance, not the prototype. 
   Use them only when context binding is critical (e.g., React handlers).
*/
💡 Performance Tip: Prefer standard methods over arrow functions in classes unless you specifically need to preserve this context for event listeners.

Senior Engineer's Checklist:

  • ✅ Encapsulation: Use #private fields for security-sensitive data.
  • ✅ Inheritance: Use super to extend parent behaviors rather than rewriting them.
  • ✅ Static Blocks: Use static blocks for complex configuration validation on startup.
  • ❌ Hoisting: Remember that classes are not hoisted; you must define them before usage.
  • ✅ Strictness: Class bodies are always in "use strict" mode by default.

What's Next?

You've mastered the architectural pillars of JavaScript. Let's move to the next phase: Asynchronous JavaScript and the Event Loop.