# Understanding Object-Oriented Programming in JavaScript

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

* * *

## What Is Object-Oriented Programming?

![](https://cdn.hashnode.com/uploads/covers/689b6ed48e43049388b9af21/c06d8bd7-ffb9-4616-8788-3496902ac93b.png align="center")

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:

```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.

```javascript
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

![](https://cdn.hashnode.com/uploads/covers/689b6ed48e43049388b9af21/d2644b68-95c7-4d49-aefb-0aadc02a5aca.png align="center")

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

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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.

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
// 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:

```javascript
// 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:**

```javascript
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:**

```javascript
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:**

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

**Output:**

```plaintext
--- 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:**

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

student1.printDetails();
```

**Output:**

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

**Bonus: Add a method that updates the course:**

```javascript
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!
