From Variables to Objects: Understanding OOP in JavaScript
How to use classes, constructors, and methods to write cleaner, more scalable code.

When you first start writing code, everything feels manageable. You have a few variables, maybe a function or two, and the whole thing fits on one screen. You can read it top to bottom and understand exactly what is going on. That feeling is great, and it lasts for a while.
Then your program grows. Say you are building something for college or work, and you need to track a group of candidates. You write something like this:
let student1Name = "Chintu";
let student1Age = 19;
let student1Grade = "A";
let student2Name = "Pintu";
let student2Age = 21;
let student2Grade = "B";
let student3Name = "Mintu";
let student3Age = 20;
let student3Grade = "A";
// Enter 50 more candidates
This works till the list starts to increase, and writing console.log for every candidate becomes a painful process. Adding new information becomes draining, and your code becomes more prone to typos. This is not something that is only related to new programmers. The code you are writing is functioning, but it does not scale. It is also fragile in ways that are not visible until something goes wrong.
There are a few principles that good programmers use to avoid situations like this, and they each have a name:
Object-Oriented Programming brings these principles together. You define the candidates using a template to define all their properties. This helps to create as many students as needed, tracking all the changes made. This template is known as a class.
What Does "Object-Oriented" Actually Mean?
Object-Oriented Programming is a style of writing code where you group related data and behaviour together into something called an object. A collection of properties is combined under one variable name, carrying methods along with it.
Consider a hospital that manages patients. The information of a patient, such as their name, age, and diagnosis are not kept in separate rooms. A single patient record is kept in one place. A doctor looks at the record, updates it, and reads from it. The data and the actions on that data live together. That is exactly what OOP is trying to replicate in code.
Real Life Analogy: Phone
Apple did not just create a single iPhone 17; they created a model defining the iPhone 15 as a device with an exact display size, camera, battery, call feature, and a camera. This specification is not an actual phone; rather, it is a description of what the phone will be.
Using this single specification, the factory produces millions of actual iPhones. The iPhone 17 owned by you and your friend are completely different physical objects. You may have an iPhone 17 that has 128GB of memory, and your friend may own an iPhone 17 your friend has 256GB of memory. You have two different iPhones. However, your iPhone and your friend's iPhone are both produced using the same model definition. Consequently, the way your iPhone and your friend's iPhone function is the same.
In JavaScript, the class corresponds to the model definition of the phone. The individual phones manufactured from that class model definition correspond to the objects. You only define the class once, and you create objects that correspond to that class as needed. Each object is unique, but all objects will share the same structure and behaviour as per the definition of the class.
Writing A Class
The earlier problem can be solved by using a class describing the properties, which allows you to generate many users or objects from one.
SYNTAX:
class ClassName {
// code goes here
}
This is how class is declared, where class is a keyword followed by the name of the class that starts with a capital letter, which creates a visual difference between a regular variable and a class.
The Constructor
Whenever a new class is created, JavaScript invokes a method called the constructor. Let's consider an example of a student filling out an enrollment form that would collect information and store it in an object.
class Student {
constructor(name, age, grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
}
// Creating student objects from the class
const ram = new Student("Ram", 19, "A");
const shayam = new Student("Shyam", 21, "B");
console.log(ram.name); // "Ram"
console.log(shayam.age); // 21
When you write new Student("Ram", 19, "A"), JavaScript creates a new empty object and then runs a constructor to store the value. Inside the constructor, this refers to a brand new object. Hence, this.name = name indicates to take whatever is passed in as name and attach it to this new object as a property.
this? The keyword this inside a class always refers to the specific object that was just created. When ram is created, this is ram. When shayam is created, this is shayam. Each object is its own separate thing with its own data attached.
Adding Behaviour With Methods
Properties store data about an object, whereas methods define what an object can do. A Student object might hold a name and age, but it can also introduce itself, display its grade, or check whether it passed a course.
Methods are just functions, but they live inside the class and have access to the object's own data via this.
class Student {
constructor(name, age, grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
// Method: introduce the student
introduce() {
return `Hi, my name is \({this.name} and I am \){this.age} years old.`;
}
// Method: show grade with a status
getStatus() {
if (this.grade === "A" || this.grade === "B") {
return `\({this.name} is passing with a \){this.grade}.`;
}
return `${this.name} needs extra support.`;
}
}
const karan = new Student("Karan", 18, "A");
const arjun = new Student("Arjun", 20, "C");
console.log(karan.introduce());
console.log(karan.getStatus());
console.log(arjun.introduce());
console.log(arjun.getStatus());
Notice that karan.introduce() and arjun.introduce() are both calling the same method, but each one knows its own name and age because this points to the right object each time.
Encapsulation
Encapsulation means the object's data and the code that operates on that data should be kept inside one block, and should not be accessed from outside to mess with internal values.
Here is a concrete example. Imagine a student's grade gets set to something nonsensical, like "Z" , because some part of your code sets it directly without any checks. Encapsulation is about protecting against that.
class Student {
constructor(name, age, grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
// Instead of changing grade directly, use a method
updateGrade(newGrade) {
const validGrades = ["A", "B", "C", "D", "F"];
if (validGrades.includes(newGrade)) {
this.grade = newGrade;
console.log(`\({this.name}'s grade updated to \){newGrade}.`);
} else {
console.log(`"${newGrade}" is not a valid grade.`);
}
}
introduce() {
return `Hi, I'm \({this.name}, currently at grade \){this.grade}.`;
}
}
const rahul = new Student("Rahul", 18, "B");
rahul.updateGrade("A"); //Rahul's grade updated to A.
// This will be rejected
rahul.updateGrade("Z"); // "Z" is not a valid grade.
console.log(rahul.introduce()); // Hi, I'm Rahul, currently at grade A.
Object-Oriented Programming is not about memorising syntax. It's about bringing the disconnected variables and functions under one object. The way class works as a blueprint, a constructor sets up the object, and methods provide behaviour.
REFERENCES:




