Skip to main content

Command Palette

Search for a command to run...

Understanding Object-Oriented Programming in JavaScript

Updated
โ€ข7 min read

As your programs grow, you'll find yourself creating many objects that share the same structure like multiple users, multiple products, multiple students. Typing out each one manually doesn't scale. There has to be a better way.

That better way is Object-Oriented Programming.


What Is OOP?

Object-Oriented Programming (OOP) is a style of writing code that organizes everything around objects , bundles of related data and behavior.

Instead of writing separate variables and functions scattered across your code, OOP lets you define a template once and create as many objects from it as you need. Each object gets its own data but shares the same structure and behavior.

The core idea: model your code the way you'd model the real world.


The Blueprint Analogy

Think about a car factory. An architect designs a blueprint , it specifies that every car will have a brand, a model, a color, and the ability to start and stop. The blueprint itself isn't a car. But you can use it to manufacture as many cars as you want, each with their own specific details.

In JavaScript:

  • The blueprint is a class

  • Each car manufactured from it is an instance (an object)


What Is a Class?

A class is a template for creating objects. It defines what properties an object will have and what actions it can perform.

class Car {
  // properties and methods go here
}

That's the shell. Now let's fill it in.


The Constructor Method

The constructor is a special method inside a class that runs automatically whenever you create a new object from it. It's where you set up the initial properties.

class Car {
  constructor(brand, model, color) {
    this.brand = brand;
    this.model = model;
    this.color = color;
  }
}

this refers to the specific object being created. When you make a red Toyota, this.color becomes "red" for that object. When you make a blue Honda, this.color becomes "blue" for that one.

Creating objects from a class

Use the new keyword to create an instance:

const car1 = new Car("Toyota", "Camry", "Red");
const car2 = new Car("Honda", "Civic", "Blue");
const car3 = new Car("Ford", "Mustang", "Black");

console.log(car1.brand); // "Toyota"
console.log(car2.color); // "Blue"
console.log(car3.model); // "Mustang"

Three objects, one class, no repeated structure. That's the reusability OOP gives you.


Methods Inside a Class

A method is a function that belongs to a class โ€” it defines what an object can do.

class Car {
  constructor(brand, model, color) {
    this.brand = brand;
    this.model = model;
    this.color = color;
  }

  describe() {
    return this.color + " " + this.brand + " " + this.model;
  }

  start() {
    return this.brand + " is starting... ๐Ÿš—";
  }
}

const car1 = new Car("Toyota", "Camry", "Red");
const car2 = new Car("Honda", "Civic", "Blue");

console.log(car1.describe()); // "Red Toyota Camry"
console.log(car2.start());    // "Honda is starting... ๐Ÿš—"

Every object created from Car automatically gets describe() and start(). You define the method once and all instances share it.


A Person Example

Let's try a cleaner, more relatable example:

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

  greet() {
    return "Hi, I'm " + this.name + " and I'm " + this.age + " years old.";
  }

  isAdult() {
    return this.age >= 18;
  }
}

const alice = new Person("Alice", 25);
const bob   = new Person("Bob", 16);

console.log(alice.greet());   // "Hi, I'm Alice and I'm 25 years old."
console.log(bob.greet());     // "Hi, I'm Bob and I'm 16 years old."

console.log(alice.isAdult()); // true
console.log(bob.isAdult());   // false

Each Person object has its own name and age, but they both share the same greet() and isAdult() behavior defined in the class.


Class vs Manually Creating Objects

To appreciate why classes matter, look at what life looks like without them:

// Without a class โ€” creating 3 students manually ๐Ÿ˜ซ
const student1 = { name: "Riya",  age: 20, course: "CS" };
const student2 = { name: "Arjun", age: 21, course: "Math" };
const student3 = { name: "Priya", age: 19, course: "Physics" };

// You'd have to write a separate function for each...
function getDetails(student) {
  return student.name + " | " + student.age + " | " + student.course;
}
// With a class โ€” one template, infinite objects โœ…
class Student {
  constructor(name, age, course) {
    this.name   = name;
    this.age    = age;
    this.course = course;
  }

  getDetails() {
    return this.name + " | " + this.age + " | " + this.course;
  }
}

const s1 = new Student("Riya",  20, "CS");
const s2 = new Student("Arjun", 21, "Math");
const s3 = new Student("Priya", 19, "Physics");

console.log(s1.getDetails()); // "Riya | 20 | CS"
console.log(s2.getDetails()); // "Arjun | 21 | Math"
console.log(s3.getDetails()); // "Priya | 19 | Physics"

The structure is defined once. Adding a fourth or fortieth student takes one line.


The Idea of Encapsulation

Encapsulation means keeping related data and behavior bundled together and ideally, keeping the internal details of an object private so the outside world only interacts with it through defined methods.

In simple terms: an object should manage its own data.

class BankAccount {
  constructor(owner, balance) {
    this.owner   = owner;
    this.balance = balance;
  }

  deposit(amount) {
    this.balance += amount;
    return "Deposited โ‚น" + amount + ". New balance: โ‚น" + this.balance;
  }

  withdraw(amount) {
    if (amount > this.balance) {
      return "Insufficient funds.";
    }
    this.balance -= amount;
    return "Withdrawn โ‚น" + amount + ". New balance: โ‚น" + this.balance;
  }

  getBalance() {
    return "Balance: โ‚น" + this.balance;
  }
}

const account = new BankAccount("Alice", 1000);

console.log(account.deposit(500));   // "Deposited โ‚น500. New balance: โ‚น1500"
console.log(account.withdraw(200));  // "Withdrawn โ‚น200. New balance: โ‚น1300"
console.log(account.withdraw(2000)); // "Insufficient funds."
console.log(account.getBalance());   // "Balance: โ‚น1300"

Notice that you don't directly set account.balance = 9999. Instead, you go through deposit() and withdraw(), which contain logic to keep the data valid. The object controls its own state and that's encapsulation.


Class โ†’ Instance at a Glance


Quick Reference

// Define a class
class ClassName {
  constructor(param1, param2) {
    this.property1 = param1;
    this.property2 = param2;
  }

  methodName() {
    return this.property1; // use this to access own data
  }
}

// Create instances
const obj1 = new ClassName("value1", "value2");
const obj2 = new ClassName("other1", "other2");

// Use them
obj1.methodName();
obj2.property1;

Wrapping Up

OOP is one of the most important shifts in thinking when you move from beginner to intermediate JavaScript. You're no longer just writing a list of instructions but you're modeling the world in code.

Here's what to carry forward:

  • A class is a blueprint โ€” it defines the shape and behavior of objects

  • The constructor runs when you create a new object and sets up its initial data

  • this refers to the specific instance being created or used

  • Methods are functions inside a class โ€” they define what an object can do

  • Use new to create instances from a class

  • Encapsulation means keeping data and the logic that manages it together in one object

  • Classes shine when you need multiple objects with the same structure โ€” write once, use everywhere

Try building a Student class, create a few instances, and call a method on each. Once it clicks, you'll see OOP patterns everywhere. ๐Ÿš€