Understanding Object-Oriented Programming in JavaScript
You use a smartphone every day. You know that every contact in your phone has a name, a number, maybe a photo. Each contact looks the same structurally but they all have different data.
That right there? That's Object-Oriented Programming. You've been living it. Now let's actually understand it
What Even IS Object-Oriented Programming?
OOP (Object-Oriented Programming) is just a way of organizing your code so it's clean, reusable, and actually makes sense when you come back to it 3 months later at 2am panicking.
Instead of writing the same code over and over, you create a template and then use that template to stamp out as many copies as you need.
What is a Class in JavaScript?
A class is like a factory blueprint. It defines:
What properties (data) an object will have
What actions (methods) the object can perform
The Constructor
When you create a new object from a class, JavaScript automatically runs a special method called constructor
Creating Objects From a Class
Now let's actually build some cars from that blueprint using the new keyword:
class Car {
constructor(color, speed) {
this.color = color;
this.speed = speed;
}
}
// Creating objects (instances)
const myCar = new Car("red", 120);
const hisCar = new Car("blue", 180);
const herCar = new Car("black", 200);
console.log(myCar.color); // "red"
console.log(hisCar.speed); // 180
console.log(herCar.color); // "black"
```
Each time you write `new Car(...)`, JavaScript:
1. Creates a fresh, empty object
2. Runs the `constructor` with whatever values you passed
3. Hands you back a fully set-up object
```
new Car("red", 120)
│
▼
constructor runs
┌─────────────────┐
│ this.color = "red" │
│ this.speed = 120 │
└─────────────────┘
│
▼
Returns → myCar object ✅
Three cars. Zero repeated code. That's reusability doing its thing.
Methods — Giving Your Objects Superpowers
Properties store data. Methods are actions the object can perform. You define them right inside the class:
class Car {
constructor(color, speed) {
this.color = color;
this.speed = speed;
}
// METHOD: an action the car can perform
drive() {
console.log(`The \({this.color} car is driving at \){this.speed} km/h!`);
}
honk() {
console.log("Beep beep! 📯");
}
}
const myCar = new Car("red", 120);
myCar.drive(); // "The red car is driving at 120 km/h!"
myCar.honk(); // "Beep beep! 📯"
const hisCar = new Car("blue", 180);
hisCar.drive(); // "The blue car is driving at 180 km/h!"
Notice how myCar.drive() and hisCar.drive() print different things even though they use the same method. That's because this.color refers to each object's own color.
Encapsulation
Encapsulation sounds fancy. It just means: keep related stuff together, and hide what doesn't need to be public.
Imagine your phone. You press the volume button you don't need to know how the speaker firmware works internally. The complexity is hidden. You just get a simple interface.
In code, encapsulation means bundling your data (properties) and behavior (methods) inside the class, so the outside world only sees what it needs to:
class BankAccount {
constructor(owner, balance) {
this.owner = owner;
this._balance = balance; // _ means "treat this as private, don't touch directly"
}
deposit(amount) {
this._balance += amount;
console.log(`Deposited $${amount}. New balance: $${this._balance}`);
}
getBalance() {
return this._balance; // controlled access — you can see it, but through me
}
}
const myAccount = new BankAccount("Alex", 1000);
myAccount.deposit(500); // Deposited \(500. New balance: \)1500
console.log(myAccount.getBalance()); // 1500
// You CAN'T (shouldn't) do this:
// myAccount._balance = 999999; ← bad practice, bypasses all logic
Putting It All Together — The Person Class
Let's build one clean example that shows everything:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hey! I'm \({this.name} and I'm \){this.age} years old.`);
}
haveBirthday() {
this.age++;
console.log(`Happy Birthday \({this.name}! You're now \){this.age}! 🎂`);
}
}
const alice = new Person("Alice", 22);
const bob = new Person("Bob", 19);
alice.greet(); // Hey! I'm Alice and I'm 22 years old.
bob.greet(); // Hey! I'm Bob and I'm 19 years old.
alice.haveBirthday(); // Happy Birthday Alice! You're now 23! 🎂
alice.greet(); // Hey! I'm Alice and I'm 23 years old.
// bob is completely unaffected ✅
bob.greet(); // Hey! I'm Bob and I'm 19 years old.
One class → unlimited unique objects. Write once, use forever.
Assignment
Build a Student class from scratch:
class Student {
constructor(name, age) {
this.name = name;
this.age = age;
}
printDetails() {
console.log(`Student: \({this.name}, Age: \){this.age}`);
}
}
// Now create 3 different students
const s1 = new Student("Priya", 20);
const s2 = new Student("Jordan", 22);
const s3 = new Student("Mei", 19);
s1.printDetails(); // Student: Priya, Age: 20
s2.printDetails(); // Student: Jordan, Age: 22
s3.printDetails(); // Student: Mei, Age: 19
Once you've got that working, try adding:
A
gradeproperty (like "A", "B", "C")A
study()method that prints"${this.name} is studying hard! 📚"A
pass()method that checks if grade is "A" or "B" and prints whether they passed