Understanding Object-Oriented Programming Features in JavaScript
Hi there! I’m Maneshwar. Currently, I’m building a private AI code review tool that runs on your LLM key (OpenAI, Gemini, etc.) with flat, no-seat pricing — designed for small teams. Check it out, if that’s your kind of thing.
Object-Oriented Programming (OOP) is a paradigm that organizes code into objects—bundles of data (properties) and behavior (methods).
While JavaScript’s OOP model is prototype-based rather than class-based like Java or C#, ES6 introduced the class
syntax, making it feel much closer to traditional OOP.
In this post, we’ll explore four important OOP concepts and how they apply in JavaScript: abstract classes, concrete classes, scope visibility, and interfaces.
1. Abstract Classes
An abstract class is a class that acts as a blueprint—it cannot be instantiated directly.
Instead, other classes inherit from it and implement its abstract methods.
JavaScript doesn’t have native abstract
classes like Java, but we can mimic them:
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error("Cannot instantiate an abstract class");
}
}
// Abstract method (no implementation)
draw() {
throw new Error("Draw method must be implemented");
}
}
class Circle extends Shape {
draw() {
console.log("Drawing a circle");
}
}
const circle = new Circle();
circle.draw(); // Drawing a circle
const shape = new Shape(); // ❌ Error: Cannot instantiate an abstract class
When to use:
- To enforce a common structure for related classes.
- To share partial implementation and force subclasses to fill in the details.
2. Concrete Classes
A concrete class is a fully implemented class from which you can create objects.
It either implements all methods from its parent abstract class or stands alone.
class Rectangle {
draw() {
console.log("Drawing a rectangle");
}
}
const rect = new Rectangle();
rect.draw(); // Drawing a rectangle
When to use:
- When you have a complete implementation that can be directly used.
- When you want to define unique behavior for a specific object type.
3. Scope Visibility
Scope visibility determines where and how a class property or method can be accessed.
In JavaScript, ES2022 introduced truly private fields using #
, while public
is the default.
- Public – Accessible anywhere.
-
Private (
#
) – Accessible only inside the class. -
Protected – Not officially supported in JavaScript, but often mimicked using naming conventions like
_protected
.
Example:
class Account {
#balance = 0; // private field
constructor(owner) {
this.owner = owner; // public
}
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
const acc = new Account("Alice");
acc.deposit(100);
console.log(acc.getBalance()); // 100
console.log(acc.#balance); // ❌ Error
4. Interfaces
JavaScript doesn’t have native interfaces like Java or TypeScript, but we can simulate them with patterns or enforce them at runtime.
Example using a manual check:
const ShapeInterface = {
draw: "function",
};
function implementsInterface(obj, interfaceDef) {
for (let method in interfaceDef) {
if (typeof obj[method] !== interfaceDef[method]) {
throw new Error(`Class must implement ${method} as a ${interfaceDef[method]}`);
}
}
}
class Triangle {
draw() {
console.log("Drawing a triangle");
}
}
const tri = new Triangle();
implementsInterface(tri, ShapeInterface); // Passes
tri.draw(); // Drawing a triangle
When to use:
- To ensure different classes share a common contract.
- To make code more flexible and polymorphic.
Final Thoughts
While JavaScript doesn’t implement OOP features exactly like Java or C#, it’s flexible enough to mimic abstract classes, interfaces, and visibility controls.
ES6+ features have brought JavaScript closer to traditional OOP, while still preserving its prototype-based roots.
If you’re writing maintainable, scalable JS applications, these concepts are invaluable for structuring your code.
LiveReview helps you get great feedback on your PR/MR in a few minutes.
Saves hours on every PR by giving fast, automated first-pass reviews. Helps both junior/senior engineers to go faster.
If you’re tired of waiting for your peer to review your code or are not confident that they’ll provide valid feedback, here’s LiveReview for you.