In the previous article, we examined the importance of software design, and how all software engineering principles have been defined to address issues rather than creating more complexity.
In this article, we will begin with one of the most significant programming paradigms known as Object Oriented Programming (OOP).
But before moving into definitions, let us examine the issue first.
🤯 The Problem
Imagine you are building a user system.
Without OOP:
const user1Name = "Ashay";
const user1Email = "ashay@gmail.com";
function loginUser1() {}
function logoutUser1() {}
Now imagine:
- 10 users
- 100 users
- admins
- customers
- sellers
Everything becomes:
- duplicated
- disconnected
- hard to manage
You have:
- data scattered everywhere
- behavior scattered everywhere
This is the core problem OOP tries to solve.
🧠 The Core Idea of OOP
OOP says:
"A real-world entity should keep its own data and behavior together."
Example:
A User should contain:
- its own properties (name, email)
- its own capabilities (login, logout)
That combination becomes an object.
✨ What is an Object REALLY?
An object is:
A self-contained unit of state + behavior.
State = data
Behavior = actions/functions
Example:
const user = {
name: "Ashay",
email: "ashay@gmail.com",
login() {
console.log(`${this.name} logged in`);
}
};
Here:
| Part | Meaning |
|---|---|
| name/email | state |
| login() | behavior |
| combined together | object |
This is the true meaning of an object.
Then Why Do We Need Classes?
Now imagine creating 10,000 users.
You DON'T want:
const user1 = { ... }
const user2 = { ... }
const user3 = { ... }
You need a reusable structure.
That reusable structure is a class.
What is a Class REALLY?
A class is:
A factory/template that defines what an object should contain.
Example:
class User {
name: string;
email: string;
constructor(name: string, email: string) {
this.name = name;
this.email = email;
}
login() {
console.log(`${this.name} logged in`);
}
}
Now you can create objects easily:
const user1 = new User("Ashay","a@gmail.com");
const user2 = new User("Rahul","r@gmail.com");
Deep Understanding of new
This is VERY important.
When you do:
const user1 = new User(...)
new does several things internally:
- Creates empty object
{} - Connects object to class prototype
- Binds
thisto new object - Runs the constructor
- Returns object
💡 Important Mental Model
A class is NOT the actual thing.
It is only:
- definition
- structure
- contract
The object is the real runtime entity.
Example:
| Real World | OOP |
|---|---|
| Building map | Class |
| Actual house | Object |
| Human DNA structure | Class |
| Actual person | Object |
Common Beginner Mistake
People think:
class User {}
means “doing OOP”.
No.
Real OOP begins when you think:
- What responsibility belongs here?
- What data should this object own?
- What should be hidden?
- How should objects communicate?
- Who controls what?
That leads to:
- Encapsulation
- Abstraction
- Polymorphism
- Dependency Injection
- SOLID principles
which we’ll cover one by one.
⏭️ What's Next?
Now that we understand what OOP is and how classes and objects help organize state and behavior, an interesting question naturally arises especially for JavaScript developers.
If JavaScript already allows us to create objects using plain object literals and factory functions, why do we need classes at all?
Are classes simply syntactic sugar, or do they solve a different set of problems?
Before we dive into the core principles of OOP such as Encapsulation, Abstraction, Inheritance, and Polymorphism, we'll take a small detour to explore one of the most common debates in the JavaScript ecosystem:
Factory Functions vs Classes
We'll compare both approaches, understand their trade-offs, and discuss when each one makes sense in real-world applications.
Because before learning how to design good objects, it's worth understanding the different ways we can create them.
Top comments (0)