OOP/OOD  

Object-Oriented Programming (OOP) in JavaScript Using Classes

JavaScript has historically been a prototype-based language, but since ES6 introduced the class syntax, OOP in JavaScript has become far more intuitive and familiar to developers from C#, Java, or C++ backgrounds. While the class keyword is syntactic sugar over prototypes, it provides a clean and structured model for building scalable applications.

This article breaks down how OOP works in JavaScript using classes, covering the four pillars—Encapsulation, Abstraction, Inheritance, and Polymorphism—with practical, real-world examples.

Understanding JavaScript Classes

A JavaScript class is a template for creating objects. It bundles data (properties) and functions (methods) into a single unit.

Basic Class Example

class User {
    constructor(name, role) {
        this.name = name;
        this.role = role;
    }

    getInfo() {
        return `${this.name} is a ${this.role}`;
    }
}

const u1 = new User("Abhishek", "Developer");
console.log(u1.getInfo());

Encapsulation — Binding Data and Methods

Encapsulation protects internal object data and exposes only what is necessary.

JavaScript supports public and private fields using the # prefix.

class BankAccount {
    #balance = 0;

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

    deposit(amount) {
        this.#balance += amount;
    }

    getBalance() {
        return this.#balance;
    }
}

const acc = new BankAccount("Abhishek");
acc.deposit(1000);
console.log(acc.getBalance());

Here the balance is private and cannot be accessed outside the class.

Abstraction — Hiding Complex Logic

Abstraction means showing only the essential behavior and hiding internal complexity.

class Payment {
    pay(amount) {
        if (this.validateCard()) {
            console.log(`Paid ₹${amount}`);
        }
    }

    validateCard() {
        console.log("Card validated");
        return true;
    }
}

User interacts only with pay(), not internal validation.

Inheritance — Extending Functionality

JavaScript supports inheritance using the extends keyword.

class Vehicle {
    start() {
        return "Vehicle starting...";
    }
}

class Car extends Vehicle {
    drive() {
        return "Car is driving...";
    }
}

const c = new Car();
console.log(c.start());
console.log(c.drive());

Polymorphism — Same Method, Different Behavior

Polymorphism allows child classes to override parent methods.

class Logger {
    log(msg) {
        console.log(`Log: ${msg}`);
    }
}

class FileLogger extends Logger {
    log(msg) {
        console.log(`Writing to file: ${msg}`);
    }
}

class DbLogger extends Logger {
    log(msg) {
        console.log(`Inserting log into DB: ${msg}`);
    }
}

function doLog(logger) {
    logger.log("Application started");
}

doLog(new FileLogger());
doLog(new DbLogger());

Static Methods — Utility Without Object Creation

Static methods belong to the class itself.

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

console.log(MathHelper.add(5, 7));

Getters and Setters — Controlled Data Access

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

    get name() {
        return this._name.toUpperCase();
    }

    set name(val) {
        if (val.length > 0) this._name = val;
    }
}

const s = new Student("abhishek");
console.log(s.name);
s.name = "Rahul";
console.log(s.name);

Real-World Example: Product & Cart System

class Product {
    constructor(id, name, price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
}

class Cart {
    #items = [];

    add(product) {
        this.#items.push(product);
    }

    getTotal() {
        return this.#items.reduce((t, p) => t + p.price, 0);
    }
}

const p1 = new Product(1, "Protein", 1200);
const p2 = new Product(2, "Creatine", 900);

const cart = new Cart();
cart.add(p1);
cart.add(p2);

console.log("Total:", cart.getTotal());

Why Use OOP in JavaScript?

OOP makes JavaScript code:

  • More structured

  • More reusable

  • Closer to backend OOP languages like C#

  • Better for complex apps (React, Node.js services, game engines)

Summary

JavaScript’s class-based OOP is powerful despite being syntactic sugar over prototypes. It supports the full range of OOP concepts—encapsulation, abstraction, inheritance, and polymorphism—while allowing developers to write clean, maintainable, and scalable code. Whether you're building frontend UI systems or backend services in Node.js, OOP with classes remains a highly effective architectural approach.