Skip to main content

Command Palette

Search for a command to run...

Understanding Object-Oriented Programming in JavaScript

Updated
11 min read
Understanding Object-Oriented Programming in JavaScript

A beginner friendly guide to writing organised, reusable code, with real-life analogies.


What Is Object-Oriented Programming?

Imagine a car factory.

The factory doesn't build one car and stop. It uses a blueprint, a single design document that describes what every car should look like: 4 wheels, an engine, a colour, a model name, the ability to accelerate, the ability to brake.

From that one blueprint, the factory can produce thousands of cars. Each car is its own separate thing, one might be red, another blue, but they all share the same structure because they came from the same blueprint.

Object-Oriented Programming (OOP) works the same way.

  • The blueprint is called a Class

  • The cars produced from it are called Objects

OOP is a way of writing code where you:

  1. Define a blueprint (class) that describes the structure and behaviour of something

  2. Create as many objects as you need from that blueprint

  3. Reuse your code instead of writing the same thing over and over

Without OOP, if you wanted to represent 100 students in your code, you'd write 100 separate objects by hand. With OOP, you write one Student class, and create 100 objects from it in seconds.


Four Ideas Behind OOP

OOP is built around a few core ideas. Don't worry about memorising these, just read them and let the concepts settle as you see examples.

  1. Class — the blueprint

  2. Object — a real thing made from the blueprint

  3. Properties — the data (name, age, colour)

  4. Methods — the actions (drive, brake, printDetails)

We will see all of these through examples right now.


What Is a Class?

A class is a template. It describes:

  • What data an object will hold (properties)

  • What actions an object can perform (methods)

Here is the simplest possible class in JavaScript:

class Car {
  // properties and methods go here
}

That's it, a class starts with the class keyword, followed by a name (always capitalised by convention), followed by curly braces.

Convention: Class names always start with a capital letter. Car, Person, Student, not car, person, student.

Right now this class is empty. Let's fill it in.


The Constructor Method

When you create an object from a class, JavaScript needs to know: what should this object's starting values be?

That's the job of the constructor.

The constructor is a special method inside a class that runs automatically every time you create a new object. It sets up the object's initial properties.

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

Let's break this down piece by piece:

  • constructor(brand, colour) — this method accepts two inputs when a new car is created

  • this — refers to the specific object being created right now. Think of this as saying "this particular car"

  • this.brand = brand — stores the incoming brand value on the object

  • this.colour = colour — stores the incoming colour value on the object

So every Car object will have its own brand and colour, set at the moment it's created.


Creating Objects from a Class

To create an object from a class, you use the new keyword:

let car1 = new Car("Toyota", "Red");
let car2 = new Car("Honda", "Blue");

Step by step, what happens when you write new Car("Toyota", "Red"):

  1. JavaScript creates a brand new empty object

  2. It calls the constructor with "Toyota" and "Red"

  3. this.brand is set to "Toyota" and this.colour is set to "Red"

  4. That object is returned and stored in car1

Now let's access the properties:

console.log(car1.brand);   // Toyota
console.log(car1.colour);  // Red
console.log(car2.brand);   // Honda
console.log(car2.colour);  // Blue

car1 and car2 are completely separate objects. Changing one does not affect the other. But they were both made from the same Car blueprint.

This is the power of OOP, one blueprint, many objects.


Adding Methods to a Class

A method is a function that lives inside a class. It defines something the object can do.

Let's add a describe method to our Car class:

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

  describe() {
    console.log("This car is a " + this.colour + " " + this.brand + ".");
  }
}

Now every Car object can call the describe method:

let car1 = new Car("Toyota", "Red");
let car2 = new Car("Honda", "Blue");

car1.describe();   // This car is a Red Toyota.
car2.describe();   // This car is a Blue Honda.

Notice this.brand and this.colour inside the method, when car1 calls describe(), this refers to car1, so it uses car1's own data. When car2 calls it, this refers to car2. Same method, different data, that's the beauty of it.


A More Complete Example: Person Class

Let's build a fuller example with a Person class that has more properties and multiple methods.

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

  greet() {
    console.log("Hi! My name is " + this.name + ".");
  }

  describe() {
    console.log(this.name + " is " + this.age + " years old and lives in " + this.city + ".");
  }
}

Creating objects and calling methods:

let person1 = new Person("Rahul", 25, "Mumbai");
let person2 = new Person("Priya", 22, "Delhi");

person1.greet();     // Hi! My name is Rahul.
person1.describe();  // Rahul is 25 years old and lives in Mumbai.

person2.greet();     // Hi! My name is Priya.
person2.describe();  // Priya is 22 years old and lives in Delhi.

We wrote the greet and describe methods once inside the class. But every object we create gets to use them. 100 people, still just two method definitions.


What Is Encapsulation?

Encapsulation sounds like a big word, but the idea is simple:

Keep the data and the actions that work on that data together, in one place.

In our Person class, the data (name, age, city) and the actions that use that data (greet, describe) all live together inside the class. That's encapsulation.

It also means the object manages its own data. You don't need to know exactly how describe() works inside, you just call it and it gives you the result. The details are hidden away inside the object.

Think of a TV remote. You press the volume button and the volume goes up. You don't need to know the circuit diagram, the remote handles it internally. That's encapsulation in everyday life.

This makes your code:

  • Organised — everything related to a Person is inside the Person class

  • Safe — the internal workings are not exposed unnecessarily

  • Easy to use — just call the method, the object handles the rest


Updating Properties After Creation

You can still update an object's properties after it has been created:

let person1 = new Person("Rahul", 25, "Mumbai");
console.log(person1.age);   // 25

person1.age = 26;
console.log(person1.age);   // 26

You can also write a method inside the class specifically for updating a property:

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

  birthday() {
    this.age = this.age + 1;
    console.log("Happy Birthday " + this.name + "! You are now " + this.age + ".");
  }
}

let person1 = new Person("Rahul", 25, "Mumbai");
person1.birthday();   // Happy Birthday Rahul! You are now 26.
person1.birthday();   // Happy Birthday Rahul! You are now 27.

Why OOP Makes Code Reusable

Let's say you're building a school app and need 5 student records. Without OOP:

// Without OOP — repetitive and messy
let student1 = { name: "Rahul", age: 20, course: "Math" };
let student2 = { name: "Priya", age: 21, course: "Science" };
let student3 = { name: "Aman", age: 22, course: "History" };
// ...and you'd have to manually write a print function for each one

With OOP:

// With OOP — clean and reusable
class Student {
  constructor(name, age, course) {
    this.name = name;
    this.age = age;
    this.course = course;
  }

  printDetails() {
    console.log(this.name + " | Age: " + this.age + " | Course: " + this.course);
  }
}

let s1 = new Student("Rahul", 20, "Math");
let s2 = new Student("Priya", 21, "Science");
let s3 = new Student("Aman", 22, "History");

s1.printDetails();   // Rahul | Age: 20 | Course: Math
s2.printDetails();   // Priya | Age: 21 | Course: Science
s3.printDetails();   // Aman | Age: 22 | Course: History

The printDetails method is written once, but works perfectly for every student. Add 50 more students, still just one method definition.


Assignment

Write this program yourself, it brings everything from this blog together.


The Task: Student Class

Step 1: Create the class:

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

  printDetails() {
    console.log("--- Student Details ---");
    console.log("Name   : " + this.name);
    console.log("Age    : " + this.age);
    console.log("Course : " + this.course);
  }
}

Step 2: Create multiple student objects:

let student1 = new Student("Rahul", 20, "Computer Science");
let student2 = new Student("Priya", 21, "Mathematics");
let student3 = new Student("Aman", 19, "Physics");

Step 3: Call the method on each object:

student1.printDetails();
student2.printDetails();
student3.printDetails();

Output:

--- Student Details ---
Name   : Rahul
Age    : 20
Course : Computer Science
--- Student Details ---
Name   : Priya
Age    : 21
Course : Mathematics
--- Student Details ---
Name   : Aman
Age    : 19
Course : Physics

Step 4: Update a property and print again:

student1.age = 21;
student1.course = "Data Science";

student1.printDetails();

Output:

--- Student Details ---
Name   : Rahul
Age    : 21
Course : Data Science

Bonus: Add a method that updates the course:

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

  changeCourse(newCourse) {
    console.log(this.name + " changed course from " + this.course + " to " + newCourse);
    this.course = newCourse;
  }

  printDetails() {
    console.log("Name: " + this.name + " | Age: " + this.age + " | Course: " + this.course);
  }
}

let student1 = new Student("Rahul", 20, "Math");
student1.changeCourse("Computer Science");
// Rahul changed course from Math to Computer Science

student1.printDetails();
// Name: Rahul | Age: 20 | Course: Computer Science

Quick Recap

Concept What It Means Example
Class Blueprint for creating objects class Car {}
Object A real instance made from a class let car1 = new Car(...)
Constructor Sets up initial properties when object is created constructor(brand, colour)
this Refers to the current object this.brand = brand
Method A function inside a class describe() { ... }
new Creates a new object from a class new Car("Toyota", "Red")
Encapsulation Keeping data and actions together in one place Everything in the class

Key Takeaways

  • A class is a blueprint, it defines the structure and behaviour of objects

  • An object is a real instance created from that blueprint using new

  • The constructor runs automatically when you create a new object and sets its starting values

  • this refers to the specific object that is currently being worked with

  • Methods are functions inside a class that describe what an object can do

  • Encapsulation means keeping related data and actions bundled together in one place

  • OOP makes your code reusable, write once, use for as many objects as you need

OOP might feel a little abstract at first, but the more you build with classes, the more natural it becomes. Start small, a Person, a Student, a Car, and before long you'll be using classes everywhere. They are the foundation of almost all large JavaScript applications. Keep practising!